线程属性
线程创建函数 pthread_create()的第二个参数(pthread_attr_t *attr)表示线程的属性。一般设置为NULL表示默认属性(非绑定、非分离、默认1MB的堆栈及与父进程同样级别的优先级)。线程的多项属性都是可以更改的,这些属性主要包括绑定属性、分离属性、堆栈地址、堆栈大小及优先级。下面介绍绑定属性和分离属性的基本概念
1. 绑定属性
Linux中采用“一对一”的线程机制,也就是一个用户线程对应一个内核线程。绑定属性就是指一个用户线程固定地分配给一个内核线程,因为CPU时间片的调度是面向内核线程的,因此具有绑定属性的线程可以保证在需要的时候总有一个内核线程与之对应。而非绑定属性则是指用户线程和内核线程的关系不是始终固定的,而是由系统来控制分配
2. 分离属性
分离属性是用来决定一个线程以什么样的方式来终止自已。在非分离情况下,当线程结束时,它所占用的系统资源并没有被释放,也就是没有真正终止,只有当 pthread_join() 函数返回时,创建的线程才能释放占用的系统资源。而在分离属性下,线程结束时立即释放它所占有的系统资源
3. 属性设置函数
这些属性的设置都是通过特定的函数来完成的
- 首先调用 pthread_attr_init() 函数进行初始化,之后调用属性设置函数
- 设置绑定属性,使用 pthread_attr_setscope() 函数
- 设置分离属性,使用 pthread_attr_setdetachstate() 函数
- 设置优先级,使用 pthread_attr_getschedparam() 函数获取优先级,再使用 phread_attr_setschedparam() 函数设置优先级
- 属性设置完后,使用 pthread_create() 函数创建线程
pthread_attr_init()
/*****pthread_attr_init()*****/
函数原型:int pthread_attr_init(pthread_attr_t *attr)
传 入 值:attr 线程属性结构指针
返 回 值:成功返回0;失败返回错误码
pthread_attr_setscope()
/*****pthread_attr_setscope()*****/
函数原型:int pthread_attr_setscope(pthread_attr_t *attr, int scope)
传 入 值:attr 线程属性结构指针
scope -->PTHREAD_SCOPE_SYSTEM 绑定
-->PTHREAD_SCOPE_PROCESS 非绑定
返 回 值:成功返回0;失败返回-1
pthread_attr_setdetachstate()
/*****pthread_attr_setdetachstate()*****/
函数原型:int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
传 入 值:attr 线程属性结构指针
detachstate -->PTHREAD_CREATE_DETACHED 分离
-->PTHREAD_CREATE_JOINABLE 非分离
返 回 值:成功返回0;失败返回错误码
pthread_attr_getschedparam()
/*****pthread_attr_getschedparam()*****/
函数原型:int pthread_attr_getschedparam(pthread_attr_t *attr, struct sched_param *param)
传 入 值:attr 线程属性结构指针
param 线程优先级
返 回 值:成功返回0;失败返回错误码
pthread_attr_setschedparam()
/*****pthread_attr_setschedparam()*****/
函数原型:int pthread_attr_setschedparam(pthread_attr_t *attr, struct sched_param *param)
传 入 值:attr 线程属性结构指针
param 线程优先级
返 回 值:成功返回0;失败返回错误码
4. 函数实例
创建一个具有绑定和分离属性的线程,而且主线程通过一个finish_flag标志变量来获得线程结束的消息
/*****thread_attr.c*****/
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#define REPEAT_NUMBER 5 //每个线程中的小任务数
#define DELAY_TIME_LEVELS 10.0 //小任务之间的最大时间间隔
int finish_flag = 0;
void *thrd_func(void *arg){
int delay_time = 0,count = 0;
printf("Thread is starting\n");
for(count = 0;count < REPEAT_NUMBER;count++){
delay_time = (int)(rand()*DELAY_TIME_LEVELS/(RAND_MAX)) + 1;
sleep(delay_time);
printf("\tThread: job %d delay = %d\n",count,delay_time);
}
printf("Thread finished\n");
finish_flag = 1;
pthread_exit(NULL);
}
int main(){
pthread_t thread;
pthread_attr_t attr;
int no = 0,res;
void * thrd_ret;
srand(time(NULL));
res = pthread_attr_init(&attr); //初始化线程属性对象
if(res != 0){
printf("Create attribute failed\n",no);
exit(res);
}
res = pthread_attr_setscope(&attr,PTHREAD_SCOPE_SYSTEM); //设置绑定属性
res+ = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHDE); //设置分离属性
if(res != 0){
printf("Setting attribute failed\n",no);
exit(res);
}
res = pthread_create(&thread, &attr, thrd_func, NULL);
if(res != 0){
printf("Create thread failed\n",no);
exit(res);
}
pthread_attr_destory(&attr) //释放线程属性对象
printf("Create thread sucess\n");
while(!finish_flag){
printf("Waiting for thread to finish...\n");
sleep(2)
}
return 0;
}