当前位置: 首页 > Linux

Linux系统编程——线程属性

时间:2023-04-07 01:19:50 Linux

在前面的章节中,我们调用pthread_create函数创建线程时,将第二个参数(即线程属性)设置为NULL,即使用默认属性。总的来说,使用默认属性已经可以解决我们开发过程中的大部分问题。但是,有时候我们在项目中对线程有一些特殊的要求,比如修改线程栈的大小,直接调用线程的库函数是不能满足要求的。这种情况下,我们可以直接设置线程属性。pthread_attr_t类型是一个结构体,主要包括以下属性:作用域(scope)、栈大小(stacksize)、栈地址(stackaddress)、优先级(priority)、分离状态(detachedstate)、调度策略和参数(scheduling策略和参数)。线程的默认属性是非绑定、非分离、默认栈、与父进程优先级相同。该结构的具体定义如下:typedefstruct{intetchstate;//线程的分离状态intschedpolicy;//线程调度策略structsched_pa??ramschedparam;//线程的调度参数intinheritsched;//线程的继承intcope;//线程的范围size_tguardsize;//线程栈尾部保护缓冲区的大小intstackaddr_set;//线程的堆栈设置size_tstacksize;//线程栈的大小}pthread_attr_t;主要结构体成员:1.线程分离状态:etchstate2.线程栈大小(默认平均分配):stacksize3.线程栈守卫缓冲区大小(位于栈尾):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()函数对其进行回收时,创建的线程才会终止,自身占用的系统资源才能得到释放。.分离状态:如果线程设置为分离状态,它会主动脱离主控线程。当它自己运行完后,线程会立即终止并释放系统资源。设置线程分离状态的函数:setthreadattributeintpthread_attr_setdetachstate(pthread_attr_t*attr,intdetachstate);获取进程属性intpthread_attr_getdetachstate(pthread_attr_tattr,intdetachstate);parameter: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,voidstackaddr,size_tstacksize);成功:0;失败:错误号参数:attr:指向某个线程属性的指针stackaddr:返回获取的栈地址stacksize:返回获取的栈大小线程的栈大小当系统中线程较多时,可能需要减小默认值stacksizeofeachthreadSize,防止进程的地址空间用完。当线程调用的函数分配了很大的局部变量或者函数调用层次很深时,可能需要增加线程栈的默认大小。函数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;内部错误,分离状态,我=1;pthread_attr_t属性;size_t堆栈大小;//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)//默认不分离printf("threadjoin\n");否则打印f("线程未知\n");/*设置线程分离属性*/pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);while(1){/*在堆上申请内存,指定线程栈的起始地址和大小*/stackaddr=malloc(SIZE);如果(stackaddr==NULL){perror("malloc");退出(1);}堆栈大小=大小;pthread_attr_setstack(&attr,stackaddr,stacksize);堆栈空间大小err=pthread_create(&tid,&attr,th_fun,NULL);if(err!=0){printf("%s\n",strerror(err));退出(1);}printf("%d\n",i++);}pthread_attr_destroy(&attr);return0;}更多精彩内容请关注公众号良旭Linux,在公众号回复1024免费获得5T技术资料,包括:Linux、C/C++、Python、RaspberryPi、Embedded、Java、Artificial智能等公众号回复群,邀您加入专家云技术交流群。最后,最近有很多朋友找我要一份Linux学习路线图,所以我结合自己的经验,利用业余时间熬夜一个月,整理了一本电子书。无论你是面试还是自我提升,相信都会对你有所帮助!免费送给大家,只求大家给我点个赞!电子书|LinuxDevelopmentLearningRoadmap也希望有小伙伴可以和我一起把这本电子书做得更完美!获得?希望老铁们来个三连击,让更多人看到这篇文章。推荐阅读:干货|程序员和高级架构师免费发送工件的必备资源|支持搜索的资源网站