六、Linux下线程属性初始化、销毁、设置和获得分离属性

一、线程的属性

线程具有属性,用pthread_attr_t表示,在对该结构进行处理之前必须进行初始化,在使用后需要对其去除初始化。
我们用pthread_attr_init函数对其初始化,用pthread_attr_destroy对其去除初始化。

a、初始化一个线程对象的属性
int pthread_attr_init(pthread_attr_t *attr);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
    说  明:Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。
            pthread_attr_init实现时为属性对象分配了动态内存空间。
    头文件:#include <pthread.h>
    
b、销毁一个线程属性对象
int pthread_attr_destroy(pthread_attr_t *attr);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr       指向一个线程属性的指针
    说  明:经pthread_attr_destroy去除初始化之后的pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。
    头文件:#include <pthread.h>

调用pthread_attr_init之后,pthread_t结构所包含的内容就是操作系统实现支持的线程所有属性的默认值。
如果要去除对pthread_attr_t结构的初始化,可以调用pthread_attr_destroy函数。如果pthread_attr_init实现时为属性对象分配了动态内存空间,pthread_attr_destroy还会用无效的值初始化属性对象,因此如果经pthread_attr_destroy去除初始化之后的pthread_attr_t结构被pthread_create函数调用,将会导致其返回错误。

线程属性的结构体如下:


typedef struct
{

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

} pthread_attr_t;

二、线程的分离状态

线程的分离状态决定一个线程以什么样的方式来终止自己。
在默认情况下线程创建是非分离状态的,这种情况下,原有的线程等待创建的线程结束。只有当pthread_join()函数返回时,创建的线程才算终止,才能释放自己占用的系统资源。

而分离线程不是这样子的,它没有被其他的线程所等待,自己运行结束了,线程也就终止了,马上释放系统资源。程序员应该根据自己的需要,选择适当的分离状态。所以如果我们在创建线程时就知道不需要了解线程的终止状态,则可以pthread_attr_t结构中的detachstate线程属性,让线程以分离状态启动。

a、获取线程分离状态属性
int pthread_attr_getdetachstate(pthread_attr_t *attr, int *detachstate);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr          指向一个线程属性的指针
            detachstate   保存返回的分离状态属性
    说  明:获取线程分离状态属性
    头文件:#include <pthread.h>
    
b、修改线程分离状态属性
int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate);
    返回值:若是成功返回0,否则返回错误的编号
    形  参:
            attr        指向一个线程属性的指针
            detachstat  有两个取值
                        PTHREAD_CREATE_DETACHED(分离)
                        PTHREAD_CREATE_JOINABLE(非分离)
    说  明:Posix线程中的线程属性pthread_attr_t主要包括scope属性、detach属性、堆栈地址、堆栈大小、优先级。
    头文件:#include <pthread.h>

可以使用pthread_attr_setdetachstate函数把线程属性detachstate设置为下面的两个合法值之一:
设置为PTHREAD_CREATE_DETACHED,以分离状态启动线程;
或者设置为PTHREAD_CREATE_JOINABLE,正常启动线程。可以使用pthread_attr_getdetachstate函数获取当前的datachstate线程属性。

三、线程属性的例程

本例程一个线程设置默认的非分离的属性,一个设置分离属性。设置线程属性后,再调用pthread_join()函数,确认非分离属性的线程在结束后调用pthread_join()函数才能释放资源,分离属性的线程结束后自动释放资源。

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

/*输出状态的属性*/
void out_state(pthread_attr_t* attr)
{
	int state;
	if(pthread_attr_getdetachstate(attr,&state)!=0)
	{
		perror("get detach state error!\r\n");	
	}
	else
	{
		if(state==PTHREAD_CREATE_JOINABLE)
		{
			printf("joinable state!\r\n");
		}
		else	
		    if(state==PTHREAD_CREATE_DETACHED)
			{
				printf("detach state!\r\n");
			}
			else
			{
				printf("error state!\r\n");
			}
	}
}
/*线程功能函数*/
void *thread_fn(void *arg)
{
	int i,sum;
	for(i=0;i<100;i++)
	{
		sum+=i;
	}
	return (void*)sum;
}
int main()
{
	
	int err;
    int result;
	/*创建两个线程,一个默认线程与一个分离线程*/
	pthread_t th_fn,detach_fn;
	/*定义线程属性*/
	pthread_attr_t attr;
	/*初始化线程的属性*/
	pthread_attr_init(&attr);
	/*输出线程属性*/
	out_state(&attr);
	
	/*以默认属性创建线程,默认创建的线程是非分离的,线程结束后不释放资源*/	
	if((err=pthread_create(&th_fn,&attr,thread_fn,(void*)0))!=0)
	{
		perror("th_fn tread create fail!\r\n");
	}
		
	if(err=pthread_join(th_fn,(void*)&result)!=0)
	{
		perror("pthread_join error!\r\n");	
	}
	else
	{
		printf("Thread return is %d\r\n",(int)result);
	}
	printf("-------------------------------------------------\n");
	/*以分离属性创建线程,线程结束后自动释放资源*/
	pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
	out_state(&attr);	
	if((err=pthread_create(&detach_fn,&attr,thread_fn,(void*)0))!=0)
	{
		perror("detach_fn tread create fail!\r\n");
	}
		
	if(err=pthread_join(detach_fn,(void*)&result)!=0)
	{
	//	perror("pthread_join error!\r\n");	
		fprintf(stderr,"%s\n",strerror(err));
	}
	else
	{
		printf("detach return is %d\r\n",(int)result);
	}
	
	
	/*销毁线程属性*/
	pthread_attr_destroy(&attr);
	printf("0x%lx finished\r\n",pthread_self());
	sleep(1);
	return 0;
}

输出的结果:可看到分离属性的线程,pthread_join()之后会出现出错,且operation not permitted。
在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值