【pthread_detach/pthread_join】pthread_detach()与pthread_join的区别?

简洁

创建linux线程,创建后可以设置其为(与主线程)分离状态/结合状态。

简单来说:

 pthread_detach()即主线程与子线程分离,子线程结束后,资源自动回收。由系统自动释放

pthread_join()即是子线程合入主线程,主线程阻塞等待子线程结束,然后回收子线程资源。

 

详细


一、创建分离线程

有两种方式创建分离线程:

(1)在线程创建时将其属性设为分离状态(detached);

(2)在线程创建后将其属性设为分离的(detached)。

二、分离线程的作用

由系统来回收线程所占用资源。

三、实例


#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/types.h>
#include <dirent.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include <time.h>

void* thread1(void *arg)
{
    while (1)
    {
        usleep(100 * 1000);
        printf("thread1 running...!\n");
    }
    printf("Leave thread1!\n");

    return NULL;
}

int main(int argc, char** argv)
{
    pthread_t tid;

    pthread_create(&tid, NULL, (void*)thread1, NULL);
    pthread_detach(tid);  // 使线程处于分离状态
    sleep(1);
    printf("Leave main thread!\n");
    pthread_exit("end"); //这个地方执行后,子进程并没有退出
//    return 0; //return后,系统会调用_exit,所有进程都会退出。
}

#gcc a.c -lpthread

#./a.out
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
Leave main thread!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!

pthread_exit("end"); //这个地方执行后,子进程并没有退出
可以看出main线程退出后,thread_1并没有退出。

$ cat a.c
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/types.h>
#include <dirent.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include <time.h>

void* thread1(void *arg)
{
    while (1)
    {
        usleep(100 * 1000);
        printf("thread1 running...!\n");
    }
    printf("Leave thread1!\n");

    return NULL;
}

int main(int argc, char** argv)
{
    pthread_t tid;

    pthread_create(&tid, NULL, (void*)thread1, NULL);
    pthread_detach(tid);  // 使线程处于分离状态
    sleep(1);
    printf("Leave main thread!\n");
    return 0; //return后,系统会调用_exit,所有进程都会退出。
}

$ ./a.out
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
Leave main thread!

 return 0; //return后,系统会调用_exit,所有进程都会退出。

可以看出main线程return后,子线程也退出了。

 

如果把pthread_deteach改为pthread_join,因为子线程是while(1)所以主线程也不会退出(因为只有子线程退出后 主线程才会执行pthread_join后面的代码)。

linjuntao@linjuntao:~/work/mt8516-p1v2/build/tmp/deploy/images/aud8516p1v2-slc-bluez$ cat a.c
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/types.h>
#include <dirent.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include <time.h>

void* thread1(void *arg)
{
    while (1)
    {
        usleep(100 * 1000);
        printf("thread1 running...!\n");
    }
    printf("Leave thread1!\n");

    return NULL;
}

int main(int argc, char** argv)
{
    pthread_t tid;

    pthread_create(&tid, NULL, (void*)thread1, NULL);
    //pthread_detach(tid);  // 使线程处于分离状态
    pthread_join(tid,NULL);  //使线程处于结合状态
    sleep(1);
    printf("Leave main thread!\n");
    return 0;
}

linjuntao@linjuntao:~/work/mt8516-p1v2/build/tmp/deploy/images/aud8516p1v2-slc-bluez$ ./a.out
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!

这可以在main中使用pthread_cancel,明确退出子线程。

 

---------------------
原文:https://blog.csdn.net/linchuanzhi_886/article/details/80406608

调用pthread_join 后只有子线程退出后 主线程才会执行pthread_join后面的代码,用途:
如果主线程处理完其他的事务后,需要用到子线程的处理结果,也就是主线程需要等待子线程执行完成之后再结束,这个时候就要用到pthread_join()方法

 

#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <semaphore.h>
#include <sys/types.h>
#include <dirent.h>
#include <pthread.h>
#include <errno.h>
#include <signal.h>
#include <time.h>

void* thread1(void *arg)
{ int i = 0;
    while (i++ < 5)
    {
        usleep(100 * 1000);
        printf("thread1 running...!\n");
    }
    printf("Leave thread1!\n");

    return NULL;
}

int main(int argc, char** argv)
{
    pthread_t tid;

    pthread_create(&tid, NULL, (void*)thread1, NULL);
    //pthread_detach(tid);  // 使线程处于分离状态
    pthread_join(tid,NULL);  //使线程处于结合状态
    sleep(1);
    printf("Leave main thread!\n");
    return 0;
}


thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
thread1 running...!
Leave thread1!
Leave main thread!


代码二:

#include "stdafx.h"
#include <pthread.h>
#include <stdio.h>
#include <Windows.h>
#pragma comment(lib, "pthreadVC2.lib")
 
static int count = 0;
 
void* thread_run(void* parm)
{
    for (int i=0;i<5;i++)
    {
        count++;
        printf("The thread_run method count is = %d\n",count);
        Sleep(1000);
    }
    return NULL;
}
 
int main()
{
    pthread_t tid;
    pthread_create(&tid, NULL, thread_run,NULL);
    // 加入pthread_join后,主线程"main"会一直等待直到tid这个线程执行完毕自己才结束
    // 一般项目中需要子线程计算后的值就需要加join方法
    pthread_join(tid,NULL);
    // 如果没有join方法可以看看打印的顺序
    printf("The count is = %d\n",count);
    getchar();
    return 0;
}
---------------------
原文:https://blog.csdn.net/dinghqalex/article/details/42921931

加了pthread_join()方法的打印:

如果把里面的pthread_join()方法注释掉的打印:

------------------------------------------------------------------------------以下为以前的认知----------------------------

前言:
1.linux线程执行和windows不同,pthread有两种状态joinable状态和unjoinable状态,如果线程是joinable状态,当线程函数自己返回退出时或pthread_exit时都不会释放线程所占用堆栈和线程描述符(总计8K多)只有当你调用了pthread_join之后这些资源才会被释放。若是unjoinable状态的线程,这些资源在线程函数退出时或pthread_exit时自动会被释放
2.unjoinable属性可以在pthread_create时指定,或在线程创建后在线程中pthread_detach自己, 如:pthread_detach(pthread_self()),将状态改为unjoinable状态,确保资源的释放。或者将线程置为 joinable,然后适时调用pthread_join.
3.其实简单的说就是在线程函数头加上 pthread_detach(pthread_self())的话,线程状态改变,在函数尾部直接 pthread_exit线程就会自动退出。省去了给线程擦屁股的麻烦。
原文:https://blog.csdn.net/weibo1230123/article/details/81410241
 

简单来说:

 pthread_detach()即主线程与子线程分离,子线程结束后,资源自动回收。由系统自动释放

pthread_join()即是子线程合入主线程,主线程阻塞等待子线程结束,然后回收子线程资源。

 

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

    默认情况下,线程被创建成可结合的。为了避免存储器泄漏,每个可结合线程都应该要么被显示地回收,即调用pthread_join;要么通过调用pthread_detach函数被分离。

[cpp]

int pthread_join(pthread_t tid, void**thread_return);  若成功则返回0,若出错则为非零。 

 

 线程通过调用pthread_join函数等待其他线程(调用者-母线程?)终止。pthread_join函数分阻塞,直到线程tid终止,将线程例程返回的(void*)指针赋值为thread_return指向的位置,然后回收已终止线程占用的所有存储器资源。

 

[cpp] int pthread_detach(pthread_t tid); 若成功则返回0,若出错则为非零。 

 

    pthread_detach用于分离可结合线程tid。线程能够通过以pthread_self()为参数的pthread_detach调用来分离它们自己。

    如果一个可结合线程结束运行但没有被join,则它的状态类似于进程中的Zombie Process,即还有一部分资源没有被回收,所以创建线程者应该调用pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源。

    由于调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此。例如,在Web服务器中当主线程为每个新来的连接请求创建一个子线程进行处理的时候,主线程并不希望因为调用pthread_join而阻塞(因为还要继续处理之后到来的连接请求),这时可以在子线程中加入代码

    pthread_detach(pthread_self())

或者父线程调用

    pthread_detach(thread_id)(非阻塞,可立即返回)

这将该子线程的状态设置为分离的(detached),如此一来,该线程运行结束后会自动释放所有资源。

 

posted on 2022-10-04 01:28  bdy  阅读(98)  评论(0编辑  收藏  举报

导航