您的位置:首页 > 运维架构 > Linux

Linux线程浅析[线程初始化和销毁,线程分离]

2017-03-27 23:19 211 查看

Linux线程浅析[线程初始化和销毁,线程分离]

线程的初始化和销毁

什么是线程的分离

线程分离函数

线程的初始化和销毁

回想一下线程的创建pthread_create的时候,第二个参数是pthread_attr_t,那么这个参数类型代表的是什么??attr是特征特性的缩写,所以这个参数的意思大概是创建线程的特征特性.

所以先了解一下这个参数的结构体类型:

typedef struct{
int etachstate; //线程的分离状态
int schedpolicy; //线程的调度策略
struct sched schedparam;//线程的调度参数
int inheritsched; //线程的继承性
int scope; //线程的作用域
size_t guardsize; //线程栈末尾的警戒缓冲区大小
int stackaddr_set; //线程栈的设置
void* stackaddr; //线程栈的启始位置
size_t stacksize; //线程栈大小
}pthread_attr_t;
在上面我们可以看到,关于这个结构体中的相关参数


 但是我们在创建一个线程的参数的时候,该怎么去创建也是一个问题.因为初始化的时候之前的例子中传入的都是NULL参数,后面会提到两个函数,是关于初始化和销毁线程参数类型的.

 

pthread_attr_init和pthread_attr_destory函数

#include<ptrhead.h>
int pthread_attr_init(pthread_attr_t *attr)
int pthead_attr_destory(pthread_attr_t *attr)
成功返回0,否则返回错误编号
pthread_attr_init函数是初始化线程参数的
pthread_attr_destory函数是销毁线程的参数的

如代码:
pthread_attr_t attr;
int err;
if((err=pthread_attr_init(&attr))!=0){
perror("create attr error");
}
if((error =pthread_attr_destory(&attr))!=0){
perror("destory attr error");
}
然后去修改结构体中的参数,在pthread_create()函数进行线程创建的时候将其传入进去;


什么是线程的分离

对比进程,子进程在销毁的时候使用wait和waitpid函数,都是去等待子进程资源的回收,同时也有singal去捕捉SIG_CHLD信号来进行调用wait函数去回收子进程,那么在线程中会不会也有这样的一个函数呢?或者类似的策略,让线程执行完毕之后,能够自动的监听检测.然后去释放其资源???答案是:我目前还没有遇到这一快相关的知识积累.但是在线程中却提供了这样一个分离策略,就是在线程执行完毕之后,能够自动回收线程所占有的资源

定义:

线程分离策略就是当线程执行完毕之后,能够由系统自动去回收线程所占有的资源的这样的一个策略.


线程分离函数

#include<pthread.h>
int pthread_attr_getdetachstat(const pthread_attr_t *restrict attr,int *detachstate);
int pthread_attr_setdetachstat(const pthread_attr_t *attr,int detachstate);
返回:成功返回0,出错返回错误编号
detachstat取值:
PTHREAD_CREATE_JOINABLE(默认值)正常启动线程
PTHREAD_CREATE_DETACHED以分离状态启动线程


 注意:

以默认方式启动的线程,在线程结束后不会自动释放占有的系统资源,要在主控线程中调用pthread_join()后才会释放

以分离状态启动的线程,在线程结束后会自动释放所占有的系统资源,这个时候就不需要调用pthread_join方法了

分离属性在网络通讯中使用的比较多;

以分离状态创建的线程就不需要去调用pthread_join了,同时以分离状态去创建的线程,是不能够获取线程返回的结果

/*
* ===========================================================================
*
*       Filename:  pthread_detach.c
*    Description:
*        Version:  1.0
*        Created:  2017年03月27日 22时02分37秒
*       Revision:  none
*       Compiler:  gcc
*         Author:   (),
*        Company:
*
* ===========================================================================
*/

#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>

void * th_function(void* argv){
int *agv = (int *) argv;
printf("agv:%d\n",agv);
int i=0;
for(i =0; i<agv; i++){
printf("thread:%lx,i:%d\n",pthread_self(),i);
sleep(1);
}
return (void*)0;
}

void outDeched(pthread_attr_t* attr){
int result_code;
int detach;
if((result_code = pthread_attr_getdetachstate(attr,&detach))!=0){
perror("get error");
}else{
if(detach == PTHREAD_CREATE_JOINABLE){
printf("PTHREAD_CREATE_JOINABLE\n");
}else if(detach ==PTHREAD_CREATE_DETACHED ){
printf("PTHREAD_CREATE_DETACHED\n");
}else{
printf("other detach");
}
}
}

int main(int argc,char * argv[]){
pthread_attr_t attr;
pthread_t turtle ,rabbit;

int err;
int entach;
if((err = pthread_attr_init(&attr)) != 0){
perror("create attr error");
}

int result_code;
//获得响应的分离策略,一般的是默认策略,即不分离状态,需要使用pthread_join去阻塞回收
if((result_code = pthread_attr_getdetachstate(&attr,&entach))!=0){
perror("get error");
}else{
}
outDeched(&attr);

int create_result;
if((create_result = pthread_create(&turtle,&attr,th_function,(void*)50))!=0){
perror("creat turtle error");
}
printf("==========================");
//给rabbit去设置detached的属性
if((result_code = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED))!=0){
perror("set error");
}
outDeched(&attr);

if((create_result = pthread_create(&rabbit,&attr,th_function,(void*)40))!=0){
perror("create rabbit error");
}

//销毁这样的一个pthread_attr_t结构体
if((err = pthread_attr_destroy(&attr))!=0){
perror("destory pthread error");
}

//因为turtle是默认的join方式进行创建的,所以其需要调用pthread_join去释放
pthread_join(turtle,NULL);
printf("main thread:%lx ended\n",pthread_self());
return 0;
}


 如上所陈述:turtle采用的是默认的JOIN方式去启动,而rabbit采用的是DETACHED的方式去启动,注意:

 detached的方式去启动的时候,是不需要通过pthread_join方法去阻塞等待回收的,并且detached的方式启动的,这个时候线程是不会有返回值返回来的

 谢谢访问,写的不好或者不对的地方,请及时指出,代码是可以直接进行run的,有兴趣的可以copy下去玩一下,线程部分相对比较难理解,但是确实是非常重要

 有兴趣的可以看一下线程的属性,这两篇博客相对来说比较全:

 

 http://blog.csdn.net/scanery/article/details/7242768

 http://www.360doc.com/content/15/0725/16/25419505_487332488.shtml

 

欢迎持续访问博客

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息