Linux - 线程属性控制

来源:互联网 发布:海关数据怎么查 编辑:程序博客网 时间:2024/05/18 02:31

线程属性

属性值不能直接设置,须使用相关函数进行操作
初始化函数为pthread_attr_init,该函数必须在pthread_create函数之前调用

typedef struct{    int  detachstate;  // 线程的分离状态    int   scope;   // 线程绑定状态    int  schedpolicy; // 线程调度策略    struct sched_param schedparam; // 线程的调度参数    int   inheritsched;  //线程的继承性    size_t  guardsize; // 线程栈末尾的警戒缓冲区大小    void *  stackaddr;  // 线程栈的位置    size_t  stacksize;   // 线程栈的大小}pthread_attr_t;

删除线程属性对象

函数原型int pthread_attr_destroy(pthread_attr_t *attr); 返回值成功返回0出错,返回其他值说明删除属性对象占用的内存调用这个函数后,相应的属性对象无效 

线程分离状态(detachstate)

决定线程以何种方式终止自己非分离状态原有的线程等待创建的线程结束只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源分离线程没有被其他的线程所等待,自己运行结束后终止线程,马上释放系统资源线程分离状态相关函数pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)detachstate选值PTHREAD_CREATE_DETACHED(分离线程) PTHREAD _CREATE_JOINABLE(非分离线程)int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate); 

线程绑定scope

轻量级进程
可理解为内核线程,位于用户层和系统层之间
系统通过轻量级进程实现对线程资源的分配、对线程的控制
一个轻量级进程可以控制一个或多个线程
非绑定
启动多少轻量级进程、哪些轻量级进程来控制哪些线程由系统来控制
系统的默认处理方式
绑定
某个线程固定的“绑”在一个轻量级进程之上
被绑定的线程具有较高的响应速度,这是因为CPU时间片的调度是面向轻进程的,绑定的线程可以保证在需要的时候它总有一个轻进程可用
通过设置被绑定的轻进程的优先级和调度级可以使得绑定的线程满足诸如实时反应之类的要求

线程绑定属性设置函数

函数原型pthread_attr_setscope(pthread_attr_t * attr, int scope)参数说明attr:指向属性结构的指针scope:绑定类型PTHREAD_SCOPE_SYSTEM(绑定的)PTHREAD_SCOPE_PROCESS(非绑定的)举例/*初始化属性值,均设为默认值*/pthread_attr_init(&attr);    pthread_attr_setscope(&attr, THREAD_SCOPE_SYSTEM);pthread_create(&tid, &attr, (void *) my_function, NULL);

线程调度策略schedpolicy

函数原型int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy);int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy);参数说明attr:线程属性变量policy:调度策略SCHED_FIFO:先进先出SCHED_RR:轮转法SCHED_OTHER:其它返回值成功返回0失败返回-1

线程调度参数schedparam

函数原型int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *param);int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param);参数说明attr:线程属性param:sched_param结构sched_priority:控制一个优先权值sched_get_priority_min():获取系统支持的最小优先权值sched_get_priority_max ():获取系统支持的最大优先权值

线程的继承性inheritsched

设置继承调度策略PTHREAD_INHERIT_SCHED(缺省值) 创建的线程将具有父线程的调度策略属性对象中的调度策略参数将不起作用PTHREAD_EXPLICIT_SCHED线程的调度策略和父线程无关属性对象中的调度策略参数将起作用相关设置函数int pthread_attr_setinheritsched(pthread_attr_t *tattr, int inherit); int pthread_attr_getinheritsched(pthread_attr_t *tattr, int *inherit); 

堆栈防护区guardsize

缺省情况下,线程的堆栈保护区大小因系统版本不同而异取值说明若guardsize=0,创建线程时将不会创建堆栈保护区若guardsize>0,创建线程时将至少有一个guardsize大小的堆栈保护区使用说明创建线程堆栈时,一般将guardsize参数值上舍入成系统变量PAGESIZE的整数倍,来分配堆栈保护区但程序调用pthread_attr_getguardsize()函数获得的堆栈保护区大小将是调用pthread_attr_setguardsize()函数时指定的guardsize参数值相关函数int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize); 

线程堆栈的基地址 stackaddr

默认由系统分配如果stackaddr为非空值,线程堆栈将从指定地址开始如果是NULL (缺省值) ,pthread_create()为其分配堆栈 相关函数int pthread_attr_setstackaddr(pthread_attr_t *tattr, void *stackaddr); int pthread_attr_getstackaddr(pthread_attr_t *tattr, void **stackaddr); 

线程堆栈大小stacksize

定义系统为线程分配的堆栈大小(字节)默认由系统决定大小函数原型int pthread_attr_setstacksize(pthread_attr_t *tattr, int size); int pthread_attr_getstacksize(pthread_attr_t *tattr, size_t *size); 参数说明size:线程所需堆栈的大小size=0,系统使用缺省大小在大多数情况下,缺省值是最合适的堆栈的大小不能小于系统定义的最小堆栈容量PTHREAD_STACK_MIN

线程的一次性初始化

有时需要对一些posix变量只进行一次初始化(如线程键),如果多次初始化,程序就会出现错误
在顺序编程中,常使用布尔变量来一次性初始化
控制变量被静态初始化为0,任何依赖于初始化的代码都能测试该变量
如果变量值仍然为0,则它能实行初始化,然后将变量置为1,以后检查的代码将跳过初始化
但在多线程程序设计中,事情变得非常复杂
如果多个线程并发地执行初始化序列代码,两个线程可能发现控制变量为0,并且都实行初始化,而该过程本该仅仅执行一次
初始化的状态必须由互斥量保护
对一个posix静态变量的初始化,可使用用一个互斥量对该变量的初始化进行控制
但使用pthread_once对变量进行动态初始化会方便许多

线程的一次性初始化函数

函数原型
pthread_once_t once_control=PTHREAD_ONCE_INIT;
int pthread_once(pthread_once_t *once_control, void(*init_routine)(void));
参数
once_control:控制变量,必须使用PTHREAD_ONCE_INIT宏静态地初始化
init_routine:初始化函数
说明
pthread_once函数首先检查控制变量,判断是否已经完成初始化
如果完成,则返回
否则,调用初始化函数,并且记录初始化被完成
如果在一个线程初始时,另外的线程调用pthread_once,则调用线程等待,直到那个线程完成初始化返回

线程的私有数据

背景
进程内的所有线程共享相同地址空间,任何声明为静态或外部的变量,或在进程堆声明的变量,都可以被进程所有的线程读写
怎样才能使线程序拥有自己的私有数据?
函数原型
int pthread_key_create(pthread_key key, void(*destructor)(void ));
参数
key:私有数据键
destructor:清理函数
如果该参数不为空,则当每个线程结束时,系统将调用这个函数来释放绑定在这个键上的内存块
说明
函数从线程私有数据池中分配一项,将其值赋给key供以后访问使用
无论哪个线程调用pthread_key_create(),所创建的key都是所有线程可访问的,但各个线程可根据自己的需要往key中填入不同的值,这就相当于提供了一个同名而不同值的全局变量
该函数常和函数pthread_once一起使用,以便该键只被创建一次

函数原型int pthread_setspecific(pthread_key_t key, const void *pointer) void * pthread_getspecific(pthread_key_t key) 说明pthread_setspecific()将pointer的值(不是所指的内容)与key相关联pthread_getspecific()将与key相关联的数据读出来数据类型都设为void *,因此可以指向任何类型的数据

说明
创建两个线程分别设置同一个线程私有数据为自己的线程ID
为了检验其私有性,程序错开了两个线程私有数据的写入和读出的时间
从程序运行结果可以看出,两个线程对TSD的修改互不干扰
当线程退出时,清理函数会自动执行,参数为tid

0 0
原创粉丝点击