当前位置: 首页 > 科技观察

Linux系统编程——线程属性

时间:2023-03-17 22:51:19 科技观察

在前面的章节中,我们调用pthread_create函数创建线程时,将第二个参数(即线程属性)设置为NULL,即使用默认属性。总的来说,使用默认属性已经可以解决我们开发过程中的大部分问题。但是,有时候我们在项目中对线程有一些特殊的要求,比如修改线程栈的大小,直接调用线程的库函数是不能满足要求的。这种情况下,我们可以直接设置线程属性。pthread_attr_t类型是一个结构体,主要包括以下属性:作用域(scope)、栈大小(stacksize)、栈地址(stackaddress)、优先级(priority)、分离状态(detachedstate)、调度策略和参数(scheduling策略和参数)。线程的默认属性是非绑定、非分离、默认栈、与父进程优先级相同。结构体的具体定义如下:主要结构体成员:线程分离状态:etachstate线程栈大小(默认平均分布):stacksize线程栈守卫缓冲区大小(在栈尾):guardsize线程属性值不能直接设置,必须使用相关函数进行操作。属性的初始化函数是pthread_attr_init,必须在pthread_create函数之前调用。使用后需要调用pthread_attr_destroy函数释放资源。##线程属性初始化函数原型:intpthread_attr_init(pthread_attr_t*attr);返回值:成功:0;失败:错误号。功能:初始化线程属性;注意:首先要初始化线程属性,然后调用pthread_create创建线程。##线程属性销毁函数原型:intpthread_attr_destroy(pthread_attr_t*attr);返回值:成功:0;failure:errornumber功能:破坏线程属性占用的资源##线程分离状态线程的分离状态决定了最后一个线程在终止时如何回收资源。非分离状态:线程的默认属性是非分离状态。在这种情况下,线程运行结束后,只有当其他线程调用pthread_join()函数对其进行回收时,创建的线程才会终止,自身占用的系统资源才能得到释放。.分离状态:如果线程设置为分离状态,它会主动脱离主控线程。当它自己运行完后,线程会立即终止并释放系统资源。设置线程分离状态的函数:设置线程属性intpthread_attr_setdetachstate(pthread_attr_t*attr,intdetachstate);获取进程属性intpthread_attr_getdetachstate(pthread_attr_tattr,intdetachstate);parameters:attr:指向线程属性的指针detachstate:线程分离状态PTHREAD_CREATE_DETACHED(分离线程)PTHREAD_CREATE_JOINABLE(非分离线程)##线程栈地址POSIX.1定义了两个常量_POSIX_THREAD_ATTR_STACKADDR和_POSIX_THREAD_ATTR_STACKSIZE来检测系统是否支持栈属性。也可以将_SC_THREAD_ATTR_STACKADDR或_SC_THREAD_ATTR_STACKSIZE传递给sysconf函数进行检测。当进程栈地址空间不够时,指定新线程使用malloc分配的空间作为自己的栈空间。线程的栈地址分别由pthread_attr_setstack和pthread_attr_getstack这两个函数设置和获取。设置线程栈地址:intpthread_attr_setstack(pthread_attr_tattr,voidstackaddr,size_tstacksize);成功:0;失败:错误号获取线程栈地址:intpthread_attr_getstack(pthread_attr_tattr,void**stackaddr,size_tstacksize);成功:0;failure:错误号参数:attr:指向某个线程属性的指针stackaddr:返回获取的栈地址stacksize:返回获取的栈大小##线程栈大小当系统中线程较多时,可能需要减小默认大小每个线程的堆栈,以防止进程的地址空间不够用。当线程调用的函数分配了很大的局部变量或者函数调用层次很深时,可能需要增加线程栈的默认大小。函数pthread_attr_getstacksize和pthread_attr_setstacksize可以设置或获取线程堆栈大小。设置线程堆栈大小:intpthread_attr_setstacksize(pthread_attr_t*attr,size_tstacksize);成功:0;失败:错误号获取线程堆栈大小:intpthread_attr_getstacksize(pthread_attr_tattr,size_tstacksize);成功:0;失败:错误号参数:attr:指向一个线程属性指针stacksize:返回线程的堆栈大小#include#include#include#include#include#defineSIZE0x10000void*th_fun(void*arg){while(1)sleep(1);}intmain(void){pthread_ttid;interr,detachstate,i=1;pthread_attr_tattr;size_tstacksize;//typedefsize_tunsignedintvoid*stackaddr;pthread_attr_init(&attr);pthread_attr_getstack(&attr,&stackaddr,&stacksize);pthread_attr_getdetachstate(&attr,&detachstate);if(detachstate==PTHREAD_CREATE_DETACHED)//默认是detachedprintf("threaddetached\n");elseif(detachstate==PTHREAD_CREATE_JOINABLE)//默认是非分离的while(1){/*在堆上申请内存,指定线程栈的起始地址和大小*/stackaddr=malloc(SIZE);if(stackaddr==NULL){perror("malloc");exit(1);}stacksize=SIZE;pthread_attr_setstack(&attr,stackaddr,stacksize);//借助线程属性,修改线程栈空间大小err=pthread_create(&tid,&attr,th_fun,NULL);if(err!=0){printf("%s\n",strerror(err));exit(1);}printf("%d\n",i++);}pthread_attr_destroy(&attr);return0;}本文转载有来自公众号》许良的授权世界500强外企Linux开发工程师《Linux》许良在公众号分享大量Linux干货,欢迎关注!