2.修改线程属性
(1)函数说明
读者是否还记得pthread_create 函数的第二个参数——线程的属性。在上一个实例中,将该
值设为NULL,也就是采用默认属性,线程的多项属性都是可以更改的。这些属性主要包括绑定
属性、分离属性、堆栈地址、堆栈大小、优先级。其中系统默认的属性为非绑定、非分离、缺省
1M的堆栈、与父进程同样级别的优先级。下面首先对绑定属性和分离属性的基本概念进行讲解。
· 绑定属性
前面已经提到,Linux 中采用“一对一”的线程机制,也就是一个用户线程对应一个内
核线程。绑定属性就是指一个用户线程固定地分配给一个内核线程,因为CPU时间片的调度
是面向内核线程(也就是轻量级进程)的,因此具有绑定属性的线程可以保证在需要的时候
总有一个内核线程与之对应。而与之相对的非绑定属性就是指用户线程和内核线程的关系不
是始终固定的,而是由系统来控制分配的。
· 分离属性
分离属性是用来决定一个线程以什么样的方式来终止自己。在非分离情况下,当一个线
程结束时,它所占用的系统资源并没有被释放,也就是没有真正的终止。只有当pthread_join()
函数返回时,创建的线程才能释放自己占用的系统资源。而在分离属性情况下,一个线程结
束时立即释放它所占有的系统资源。这里要注意的一点是,如果设置一个线程的分离属性,
而这个线程运行又非常快,那么它很可能在pthread_create函数返回之前就终止了,它终止以
后就可能将线程号和系统资源移交给其他的线程使用,这时调用pthread_create的线程就得到
了错误的线程号。
这些属性的设置都是通过一定的函数来完成的,通常首先调用pthread_attr_init函数进行
初始化,之后再调用相应的属性设置函数。设置绑定属性的函数为pthread_attr_setscope,设
置线程分离属性的函数为pthread_attr_setdetachstate,设置线程优先级的相关函数为
pthread_attr_getschedparam(获取线程优先级)和pthread_attr_setschedparam(设置线程优先
级)。在设置完这些属性后,就可以调用pthread_create函数来创建线程了。
(2)函数格式
所需头文件#include
函数原型int pthread_attr_init(pthread_attr_t *attr)
函数传入值attr:线程属性
函数返回值
成功:0
出错:-1
pthread_attr_setscope函数的语法要点
所需头文件#include
函数原型int pthread_attr_setscope(pthread_attr_t *attr, int scope)
函数传入值
attr:线程属性
scope: PTHREAD_SCOPE_SYSTEM:绑定
PTHREAD_SCOPE_PROCESS:非绑定
函数返回值
成功:0
出错:-1
pthread_attr_setdetachstate函数的语法要点
所需头文件#include
函数原型int pthread_attr_setscope(pthread_attr_t *attr, int detachstate)
函数传入值attr:线程属性
detachstate PTHREAD_CREATE_DETACHED:分离
PTHREAD _CREATE_JOINABLE:非分离
函数返回值
成功:0
出错:-1
pthread_attr_getschedparam函数的语法要点
所需头文件#include
函数原型int pthread_attr_getschedparam (pthread_attr_t *attr, struct sched_param *param)
函数传入值
attr:线程属性
param:线程优先级
函数返回值
成功:0
出错:-1
pthread_attr_setschedparam函数的语法要点
所需头文件#include
函数原型int pthread_attr_setschedparam (pthread_attr_t *attr, struct sched_param *param)
函数传入值
attr:线程属性
param:线程优先级
函数返回值
成功:0
出错:-1
3.使用实例
该实例将上一节中的第一个线程设置为分离属性,并将第二个线程设置为始终运行状
态,这样就可以在第二个线程运行过程中查看内存值的变化。
其源代码如下所示:
/*pthread.c*/
#include
#include
#include
/*线程一*/
void thread1(void)
{
int i=0;
for(i=0;i<6;i++){
printf("This is a pthread1.\n");
if(i==2)
pthread_exit(0);
sleep(1);
}
}
/*线程二*/
void thread2(void)
{
int i;
while(1){
for(i=0;i<3;i++)
printf("This is a pthread2.\n");
sleep(1);}
pthread_exit(0);
}
int main(void)
{
pthread_t id1,id2;
int i,ret;
pthread_attr_t attr;
/*初始化线程*/
pthread_attr_init(&attr);
/*设置线程绑定属性*/
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
/*设置线程分离属性*/
pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
/*创建线程*/
ret=pthread_create(&id1,&attr,(void *) thread1,NULL);
if(ret!=0)
{
printf ("Create pthread error!\n");
exit (1);
}
ret=pthread_create(&id2,NULL,(void *) thread2,NULL);
if(ret!=0)
{
printf ("Create pthread error!\n");
exit (1);
}
pthread_join(id2,NULL);
return (0);
}