飞凌嵌入式ElfBoard-线程之线程属性
使用pthread_create()函数创建线程的时候,函数的第二个参数attr用于指定新线程的属性,通常在创建线程之前通过 pthread_attr_t 类型的变量来配置线程属性。在不同的操作系统实现中,pthread_attr_t 的底层数据结构可能会有所不同,但我们不直接访问它的内部成员,而是通过 POSIX 提供的 pthread_attr_* 函数接口来初始化、设置或查询其属性。
简单介绍一下与线程属性相关的API接口:
|
相关API |
简要说明 |
|
基本属性管理 |
|
|
pthread_attr_init (pthread_attr_t *__attr) |
初始化 pthread_attr_t |
|
pthread_attr_destroy (pthread_attr_t *__attr) |
销毁属性对象,释放相关资源。 |
|
线程分离状态 |
|
|
pthread_attr_getdetachstate(const pthread_attr_t *__attr, int *__detachstate) |
获取线程的分离状态属性,放入 __detachstate。 |
|
pthread_attr_setdetachstate (pthread_attr_t *__attr, int __detachstate) |
设置线程的分离状态属性。 |
|
栈和保护区大小 |
|
|
pthread_attr_getguardsize (const pthread_attr_t *__attr, size_t *__guardsize) |
获取线程栈末尾的警戒缓冲区大小(防止栈溢出区域),单位是字节。 |
|
pthread_attr_setguardsize (pthread_attr_t *__attr, size_t __guardsize) |
设置线程栈末尾的警戒缓冲区大小。 |
|
pthread_attr_getstackaddr (const pthread_attr_t *__restrict __attr, void **__restrict __stackaddr) |
获取线程栈的起始地址。(返回先前设置的堆栈地址) |
|
pthread_attr_setstackaddr (pthread_attr_t *__attr, void *__stackaddr) |
设置线程栈的起始地址。根据堆栈是增加还是减少,该值必须高于或低于内存块中的所有地址。 |
|
pthread_attr_getstacksize (const pthread_attr_t *__restrict __attr, size_t *__restrict __stacksize) |
获取线程栈的大小。(返回当前使用的最小堆栈大小) |
|
pthread_attr_setstacksize (pthread_attr_t *__attr, size_t __stacksize) |
设置线程栈的大小。(添加有关启动线程所需的最小堆栈大小的信息。这个大小不能小于PTHREAD_STACK_MIN,也不能超过系统限制。) |
|
调度策略和优先级 |
|
|
pthread_attr_getschedparam (const pthread_attr_t *__restrict __attr, struct sched_param *__restrict __param) |
获取线程的调度参数(优先级),放入 __param。 |
|
pthread_attr_setschedparam (pthread_attr_t *__restrict __attr, const struct sched_param *__restrict __param) |
设置线程的调度参数(优先级)。 |
|
pthread_attr_getschedpolicy (const pthread_attr_t *__restrict __attr, int *__restrict __policy) |
获取线程的调度策略(如 SCHED_FIFO、SCHED_RR、SCHED_OTHER) |
|
pthread_attr_setschedpolicy (pthread_attr_t *__attr, int __policy) |
设置线程的调度策略。 |
|
继承和调度范围 |
|
|
pthread_attr_getinheritsched (const pthread_attr_t *__restrict __attr, int *__restrict __inherit) |
获取线程的调度属性继承方式,可以是 PTHREAD_INHERIT_SCHED 或 PTHREAD_EXPLICIT_SCHED。 |
|
pthread_attr_setinheritsched (pthread_attr_t *__attr, int __inherit) |
设置线程的调度属性继承方式。 |
|
pthread_attr_getscope (const pthread_attr_t *__restrict __attr, int *__restrict __scope) |
获取线程的作用域,可以是 PTHREAD_SCOPE_SYSTEM(系统范围)或 PTHREAD_SCOPE_PROCESS(进程内部范围)。 |
|
pthread_attr_setscope (pthread_attr_t *__attr, int __scope) |
设置线程的作用域。 |
|
栈和亲和性(Linux特有) |
|
|
pthread_attr_getstack (const pthread_attr_t *__restrict __attr, void **__restrict __stackaddr, size_t *__restrict __stacksize) |
获取线程栈的起始地址和大小。 |
|
pthread_attr_setstack (pthread_attr_t *__attr, void *__stackaddr, size_t __stacksize) |
设置线程栈的起始地址和大小。 |
|
pthread_attr_setaffinity_np (pthread_attr_t *__attr, size_t __cpusetsize, const cpu_set_t *__cpuset) |
设置线程的 CPU 亲和性,限制线程在哪些 CPU 上运行(非标准接口)。 |
|
pthread_attr_getaffinity_np (const pthread_attr_t *__attr, size_t __cpusetsize, cpu_set_t *__cpuset) |
获取线程的 CPU 亲和性(非标准接口)。 |
|
其他相关接口 |
|
|
pthread_getattr_default_np (pthread_attr_t *__attr) |
获取系统默认的线程属性(Linux扩展)。 |
|
pthread_setattr_default_np (const pthread_attr_t *__attr) |
设置系统默认的线程属性(Linux扩展)。 |
|
pthread_attr_setsigmask_np (pthread_attr_t *__attr, const __sigset_t *sigmask) |
设置线程的信号掩码(Linux扩展)。 |
|
pthread_attr_getsigmask_np (const pthread_attr_t *__attr, __sigset_t *sigmask) |
获取线程的信号掩码(Linux扩展)。 |
|
pthread_getattr_np (pthread_t __th, pthread_attr_t *__attr) |
获取现有线程的属性,适用于调试或复制线程配置。 |
这些函数使得对线程属性的管理更灵活,例如在设置优先级或栈大小时,可以根据需要对线程进行细粒度控制。
1.相关参数大致说明
1)pthread_attr_t
描述:线程属性对象,包含了线程的各种属性设置,如栈大小、调度策略、分离状态等。
2)int(整型参数)
用途:常用于获取或设置线程的状态,例如分离状态、调度策略等。
·detachstate:表示线程的分离状态,取值为 PTHREAD_CREATE_JOINABLE(可连接)或 PTHREAD_CREATE_DETACHED(已分离)。
·inherit:表示调度继承状态,取值为 PTHREAD_INHERIT_SCHED 或 PTHREAD_EXPLICIT_SCHED。
·scope:表示调度范围,取值为 PTHREAD_SCOPE_SYSTEM 或 PTHREAD_SCOPE_PROCESS。
3)struct sched_param
描述:调度参数结构体,包含线程的优先级设置。
主要成员:int sched_priority:表示线程的调度优先级。
4)size_t
描述:用于表示大小的无符号整型,常用于栈大小和保护区大小等。
·guardsize:保护区大小,指定在栈顶和栈底之间的保护区大小。
·stacksize:栈大小,指定线程的栈的大小。
5)void *(指针参数)
用途:用于指向特定的资源,如栈地址或 CPU 亲和性集等。
·stackaddr:线程栈的起始地址,用户可以通过设置这个参数来指定线程的栈位置。
·cpuset:CPU 亲和性集,用于指定线程可以运行在哪些 CPU 上。
6)cpu_set_t
描述:用于表示 CPU 亲和性集的数据结构,可以通过设置和获取特定 CPU 的亲和性。
用途:在设置线程的 CPU 亲和性时使用。
如果没有其他特别的需求,可以直接使用默认属性,不需要考虑线程相关属性的情况pthread_create()函数的第二个参数可以设置为NULL;如果需要配置用到线程的相关属性,通常会先创建一个属性对象,然后在属性对象上设置属性的值,再将属性对象传给pthread_create()函数的第二个参数;
2.使用线程属性的流程步骤一般如下
1)定义一个 pthread_attr_t 类型的变量:这个结构体用于存储线程属性。
2)初始化线程属性:使用 pthread_attr_init() 函数来初始化线程属性。
3)设置所需的线程属性:使用各种 pthread_attr_set*() 函数设置具体的属性,例如设置栈大小、调度策略等。
4)创建线程并传递属性:在调用 pthread_create() 时,将属性传递给它。
5)销毁线程属性:使用 pthread_attr_destroy() 来释放相关资源。
3.示例:使用线程属性创建一个分离线程
|
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h> void* thread_function(void* arg) { printf("Thread is running...\n"); sleep(2); // 模拟线程工作 printf("Thread is exiting...\n"); return NULL; } int main() { pthread_t thread; pthread_attr_t attr; // 初始化线程属性 pthread_attr_init(&attr);
// 设置线程为分离状态 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); // 创建线程 if (pthread_create(&thread, &attr, thread_function, NULL) != 0) { perror("Failed to create thread"); exit(EXIT_FAILURE); } // 销毁线程属性 pthread_attr_destroy(&attr); // 主线程继续执行 printf("Main thread is running...\n");
// 由于子线程是分离状态,主线程不需要调用 pthread_join sleep(3); // 等待子线程完成工作 printf("Main thread is exiting...\n");
return 0; } |
4.运行结果
|
Main thread is running... Thread is running... Thread is exiting... Main thread is exiting... |
5.代码解析
thread_function()定义一个线程将要执行的函数。pthread_t thread;定义一个线程标识符 thread,用于识别和管理线程。pthread_attr_t attr;定义一个线程属性对象 attr,用于设置线程的属性。使用 pthread_attr_init 初始化 attr 属性对象,以便后续配置线程属性。调用 pthread_attr_setdetachstate 设置线程为分离状态。分离线程在结束时会自动释放其占用的资源,不需要主线程调用 pthread_join。pthread_create()函数调用属性参数,最后销毁属性对象,然后释放相关资源。
可以将同一个线程属性对象 pthread_attr_t 应用于多个线程。这种方式有助于统一配置多个线程的属性,从而简化代码的维护和管理。设置完线程属性对象 pthread_attr_t 之后,可以通过多次调用 pthread_create 函数来创建多个线程。
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)