【pthread_join/pthread_detach踩坑

前言
线程有joinable和unjoinable两种状态,在pthread_create创建线程时默认为joinable状态,线程在该状态退出时(调用pthread_exit或线程函数返回退出时)不释放线程资源(线程描述符、线程占用堆栈);当线程处于unjoinable状态时,线程退出会自动释放线程资源。

pthread_join

对于joinable状态子线程,子线程退出时必须通过pthread_join函数释放线程资源。主线程调用该函数时阻塞在子线程上,等待子线程结束后再执行主线程函数。

#include 
int pthread_join(pthread_t pid,void **ptr);

pthread_join函数必须作用在joinable状态线程上,参数pid为线程描述符,ptr为 线程返回值,执行后主线程阻塞等待子线程结束。

示例:

#include 

void* func1(void*arg)
{
    printf("function1 is running");
    return ((void*)0);
}

int main()
{
    pthread_t pid1;
    int error;
    error = pthread_create(pid1,NULL,func1,NULL);
    if(error != 0)
    {
        err_exit(error,"creat thread failed");
    }
    error = pthread_join(pid1,NULL);
    if(error != 0)
    {
        err_exit(error,"join thread failed");
    }
    func();
    ...
    return 0;
}

子线程结束后必须执行pthread_join函数释放资源,主线程只在阻塞等待pid1线程资源释放后执行后续func()函数。 

pthread_detach

通过pthread_detach函数可以将joinable状态线程转换为unjoinable线程,unjoinable状态线程处于分离态,线程结束后自动释放资源,主线程不会在子线程结束处阻塞

#include 
int pthread_detach(pthread_t pid);

1.可以在创建子线程后将线程置为分离态

2.可以在子线程内部通过pthread_detach(thread_self)将线程置为分离态

对于分离态子线程,主线程不会阻塞等待子线程结束,存在主线程先于子线程结束情况

示例:

#include 

void* func1(void*arg)
{
    printf("function1 is running");
    return ((void*)0);
}


int main()
{
    pthread_t pid1;
    int error;
    error = pthread_create(pid1,NULL,func1,NULL);
    if(error != 0)
    {
        err_exit(error,"creat thread failed");
    }
    error = pthread_detach(pid1);
    if(error != 0)
    {
        err_exit(error,"detach thread failed");
    }
    func();
    ...
    return 0;
}

同时,可以通过设置线程属性改变线程分离状态

设置detach状态

#include 

void* func1(void*arg)
{
    printf("function1 is running");
    return ((void*)0);
}


int main()
{
    pthread_t pid1;
    int error;
    pthread_attr_t attr;   // 定义属性变量
	pthread_attr_init(&attr);  // 初始化属性
	//pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);  // 设置为以分离
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);  // 设置为可连接

    error = pthread_create(pid1,&attr,func1,NULL);
    if(error != 0)
    {
        err_exit(error,"creat thread failed");
    }
   
    func();
    ...
    pthread_attr_destroy(&attr);    
    return 0;
}

你可能感兴趣的:(linux,linux,c++)