C++ Linux多线程:各种线程属性和对它们做相关操作的函数
线程属性
pthread_attr_t 结构体定义了一套完整的线程属性:
#include <bits/ pthreadtypes.h>
#define __SIZEOF_PTHREAD_ATTR_T 36
typedef union
{
char __size[__SIZEOF_PTHREAD_ATTR_T];
long int __align;
} pthread_attr_t;
可以看到,各种线程属性都包含在一个字符数组中
各个线程属性的含义和相关函数
线程库定义了一系列函数来操作 pthread_attr_t 类型的变量,以方便我们获取和设置线程属性。
用于初始化和销毁 pthread_attr_t 类型变量的两个函数如下:
#include <pthread.h>
/* 初始化线程属性对象 */
int pthread_attr_init( pthread_attr_t* attr );
/* 销毁线程属性对象,被销毁的线程属性对象只有再次初始化后才能继续使用 */
int pthread_attr_destory( pthread_attr_t* attr );
各个线程属性以及对其相关操作的函数如下:
-
detachstate 线程脱离状态
可选值:
PTHREAD_CREATE_JOINABLE:指定线程是可以被回收的
PTHREAD_CREATE_DETACH:使调用线程脱离与进程中其他线程的同步
脱离了与其他线程同步的线程成为“脱离线程”,脱离线程将在退出时自行释放其占用的系统资源
线程创建时属性的默认值是 PTHREAD_CREATE_JOINABLE,可以用pthread_detach 函数将线程设置为脱离线程
相关函数:
/* 取得 detachstate */ int pthread_attr_getdetachstate( const pthread_attr_t *attr, int *detachstate ); /* 设置 detachstate */ int pthread_attr_setdetachstate( pthread_attr_t *attr, int detachstate );
-
stackaddr & stacksize 线程堆栈的起始地址和大小
一般来说,我们不需要自己管理线程堆栈,因为 Linux 默认为每个线程分配了足够的堆栈空间(一般是8M).
可以使用 ulimit -s 命令来查看或修改这个默认值
相关函数:
/* 取得 stackaddr */ int pthread_attr_getstackaddr( const pthread_attr_t *attr, void **stackaddr ); /* 设置 stackaddr */ int pthread_attr_setstackaddr( pthread_attr_t *attr, void *stackaddr ); /* 取得 stacksize */ int pthread_attr_getstacksize( const pthread_attr_t *attr, size_t *stacksize ); /* 设置 stacksize */ int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize ); /* 取得 stackaddr 和 stacksize */ int pthread_attr_getstack( const pthread_attr_t * attr, void **stackaddr, size_t *stacksize ); /* 设置 stackaddr 和 stacksize */ int pthread_attr_setstack( pthread_attr_t *attr, void *stackaddr, size_t stacksize );
-
guardsize 保护区域大小
如果 guardsize > 0,则系统创建线程的时候会在其堆栈的尾部额外分配guardsize 字节的空间,用于保护堆栈不被错误地覆盖
如果 guardsize = 0,则不会设置保护区域
如果使用者通过 pthread_attr_setstackaddr 函数,或 pthread_attr_setstack 函数来手动设置线程的堆栈,则guardsize 属性会被忽略
相关函数:
/* 取得 guardsize */ int pthread_attr_getguardsize( const pthread_attr_t *attr, size_t *guardsize ); /* 设置 guardsize */ int pthread_attr_setguardsize( pthread_attr_t *__attr, size_t guardsize );
-
schedparam 线程调度参数
类型:sched_param结构体
结构体成员:目前只有 shed_priority,表示线程的运行优先级
/* 取得 schedparam */ int pthread_attr_getschedparam( const pthread_attr_t *attr, struct sched_param* param ); /* 设置 schedparam */ int pthread_attr_setschedparam( pthread_attr_t *attr, const struct sched_param* param );
-
schedpolicy 线程调度策略
可选值:
SCHED_FIFO:采用先进先出调度
SCHED_RR:采用轮转算法(round-robin)调度
SCHED_OTHER:默认值
FIFO 和 RR 两种调度方法都具备实时调度功能,但只能用于以超级用户身份运行的进程
/* 取得 schedpolicy */ int pthread_attr_getschedpolicy( const pthread_attr_t *attr, int *policy ); /* 设置 schedpolicy */ int pthread_attr_setschedpolicy( pthread_attr_t *attr, int policy );
-
inheritsched 是否继承调用线程的调度属性
可选值:
PTHREAD_INHERIT_SCHED:新线程沿用创建者的线程调度参数(这种情况下再这只新线程的调度参数将没有任何效果)
PTHREAD_EXPLICIT_SCHED:表示调用者要明确指定新线程的调度参数
/* 取得 inheritsched */ int pthread_attr_getinheritsched( const pthread_attr_t *attr, int *inherit ); /* 取得 inheritsched */ int pthread_attr_setinheritsched( pthread_attr_t *attr, int inherit );
-
scope 线程间竞争 CPU 的范围
可选值:
PTHREAD_SCOPE_SYSTEM:表示目标线程与系统中所有线程一起竞争 CPU 的使用
PTHREAD_SCOPE_PROCESS:目标线程仅与其他隶属于同一进程的线程竞争 CPU 的使用
虽然 POSIX 标准定义了两个可选值,但目前 linux 只支持 PTHREAD_SCOPE_SYSTEM一种取值
/* 取得 scope */ int pthread_attr_getscope( const pthread_attr_t *attr, int *scope ); /* 设置 scope */ int pthread_attr_setscope( pthread_attr_t *attr, int scope );