通过pthread-detach()使线程分离

线程分离的意义

在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源(如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。

什么是线程分离:

简单来讲,线程分离就是当线程被设置为分离状态后,线程结束时,它的资源会被系统自动的回收,而不再需要在其它线程中对其进行 pthread_join() 操作。

为什么线程分离:

在我们使用默认属性创建一个线程的时候,线程是 joinable (即主线程和子线程时结合的)的。 joinable 状态的线程,必须在另一个线程中使用 pthread_join() 等待其结束,如果一个 joinable 的线程在结束后,没有使用 pthread_join() 进行操作,这个线程就会变成”僵尸线程”。每个僵尸线程都会消耗一些系统资源,当有太多的僵尸线程的时候,可能会导致创建线程失败。

pthread-detach()函数

函数原型:int pthread_datach(pthread_t thread);
调用该函数之后不需要 pthread_join
子线程结束后,它的资源会被系统自动回收。
子线程设置分离属性,则pthread_join不再阻塞,立刻返回,且返回值非0

代码

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

void *pthread1(void * prc)
{
        printf("pthread1 is over\n");
        sleep(10);
}
int main()
{
        pthread_t id;
        int ret;
        printf("main pthread is running\n");
        pthread_create(&id,NULL,&pthread1,NULL);
        pthread_detach(id);
        ret=pthread_join(id,NULL);
        if(ret != 0)
        {       printf("pthread_join error\n");//线程1已经被设置成分离状态,所以pthread—join不阻塞,且返回值非0

        }
        sleep(1);
        pthread_exit(0);

}
~  

执行结果

请添加图片描述

这里可以看到pthread_join的返回值是非0的,且无阻塞。

通过设置线程属性来使线程分离

  1. 线程属性
      使用pthread_create函数创建新线程时,可通过类型为pthread_attr_t的attr参数指定新线程的属性,比如可以通过设置线程栈的大小来降低内存的使用,增加最大线程个数,线程调度策略和优先级等。

pthread_attr_t结构体的主要成员:

typedef struct
{
int detachstate; //线程的分离状态
int schedpolicy; //线程调度策略
struct sched_param schedparam; //线程的调度参数
int inheritsched; //线程的继承性
int scope; //线程的作用域
size_t guardsize; //线程栈末尾的警戒缓冲区大小,默认是PAGE_SIZE(4096KB)
int stackaddr_set; //线程栈的设置
void* stackaddr; //线程栈的地址
size_t stacksize; //线程栈的大小
} pthread_attr_t;
这里可以看到pthread_attr_t结构体可以设置很多属性,本次我们主要针对线程的分离状态detachstate来进行编写。

线程属性操作函数

对线程属性变量的初始化 :int pthread_attr_init(pthread_attr_t* attr);
设置线程分离属性:int pthread_attr_setdetachstate(pthread_attr_t* attr,int detachstate);
参数:
attr : 线程属性
detachstate:
PTHREAD_CREATE_DETACHED(分离)
PTHREAD_CREATE_JOINABLE(非分离)
获取线程属性函数: int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate);
attr:线程属性
detachstate:读线程属性中的分离状态读到这个变量里

释放线程资源函数:int pthread_attr_destroy(pthread_attr_t* attr);

代码

pthread_create3.c

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
void * pthread1(void * arc)
{
        printf("pthread1 is %ld\n",pthread_self());
        return 0;
}
int main()
{
        pthread_t id;
        pthread_attr_t attr;
        int ret;
        int state;
        //初始化线程属性
        pthread_attr_init(&attr);
        //设置线程属性
        pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);

        ret=pthread_create(&id,&attr,pthread1,NULL);
        if(ret != 0)
        {
                printf("error number is %d\n",ret);
                printf("%s",strerror(ret));
        }
        //获取线程分离属性
        pthread_attr_getdetachstate(&attr,&state);
        if(state == PTHREAD_CREATE_DETACHED)
        {
                printf("设置线程分离属性成功\n");
        }
        print("main pthread is %ld\n",pthread_self());
        for(int i=0;i<5;i++)
        {
                printf("i = %d\n",i);
        }
        sleep(3);
        //销毁线程属性所占用的资源
        pthread_attr_destroy(&attr);
        return 0;
}

执行结果

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值