pthread_join和pthread_detach的用法 【】转载】

一笑奈何 提交于 2019-11-29 01:51:13

C/C++:pthread_join()和pthread_detach()的区别

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_29621351/article/details/81948850

      简单来说:pthread_detach()和pthread_join()就是控制子线程回收资源的两种不同的方式。同一进程间的线程具有共享和独立的资源,其中共享的资源有堆、全局变量、静态变量、文件等公用资源。而独享的资源有栈和寄存器,这两种方式就是决定子线程结束时如何回收独享的资源。

      pthread_detach()即主线程与子线程分离,两者相互不干涉,子线程结束同时子线程的资源自动回收。pthread_join()即是子线程合入主线程,主线程会一直阻塞,直到子线程执行结束,然后回收子线程资源,并继续执行。

代码编译过程为(文件取名main.cc)

/** 编译 -lpthread为链接pthread**/g++ -o a.out main.cc -lpthread/** 执行 **/./a.out

linux下内存占用查看指令为

/** 先找到想要查看的程序的进程号 **/ps -ef/** -d 1 表示数据刷新频率1秒 -p xxx 表示想查看的程序的进程号 **/top -d 1 -p xxx

测试程序如下

// for test#include <iostream>#include <unistd.h>#include <pthread.h> using namespace std;void* svc(void* args){    sleep(3);    cout << "111111111111111" << endl;    return nullptr;}int main(){    do    {        pthread_t threadId = 0;        const int ret = pthread_create(&threadId, 0, &svc, nullptr);        if (ret == -1)        {            cout << "error while create thread!" << endl;            return 0;       }        sleep(1)//        pthread_join(threadId, nullptr);//        cout << "222222222222222" << endl;//        pthread_detach(threadId);//        cout << "333333333333333" << endl;    }while (false);    getchar();    return 0;}

 先注销掉pthread_join()和pthread_detach()两个函数,代码中每隔1s创建一个子线程,并且子线程在执行结束后资源并没有被释放,变成了僵尸线程,此时用top明明查看进程的内存占用,发现进程占用的内存不断增大。此时若取消注释pthread_join()或者是pthread_detach()中的任意一个,再重新编译并启动程序,发现进程内存占用不会增大。因为子线程资源被释放掉了(无论是子线程自动释放还是主线程回收,都是释放)。

然后在一个子线程中观察两种释放的区别(此时不再创建多个子线程)

// for test#include <iostream>#include <unistd.h>#include <pthread.h> using namespace std;void* svc(void* args){    sleep(3);    cout << "111111111111111" << endl;    return nullptr;}int main(){    do    {        pthread_t threadId = 0;        const int ret = pthread_create(&threadId, 0, &svc, nullptr);        if (ret == -1)        {            cout << "error while create thread!" << endl;            return 0;       }        sleep(1)        pthread_join(threadId, nullptr);        cout << "222222222222222" << endl;//        pthread_detach(threadId);//        cout << "222222222222222" << endl;    } while (false);//  getchar();    return 0;}

主线程调用pthread_join()时,主线程将阻塞在这条调用语句上,不再执行下面的cout,直到子线程执行完毕后,主线程回收了子线程的资源,才会继续向下执行。这段代码的测试结果是

先输出子线程休眠三秒后打印的111111111111111,后输出pthread_join()语句之后的222222222222222,这样我们发现,在子线程执行完毕之后,主线程才继续执行pthread_join()之后的语句。而如果我们使用pthread_detach(),代码如下

// for test#include <iostream>#include <unistd.h>#include <pthread.h> using namespace std;void* svc(void* args){    sleep(3);    cout << "111111111111111" << endl;    return nullptr;}int main(){    do    {        pthread_t threadId = 0;        const int ret = pthread_create(&threadId, 0, &svc, nullptr);        if (ret == -1)        {            cout << "error while create thread!" << endl;            return 0;       }        sleep(1)//        pthread_join(threadId, nullptr);//        cout << "222222222222222" << endl;        pthread_detach(threadId);        cout << "222222222222222" << endl;    } while (false);//  getchar();    return 0;}

结果如下

主线程不会等待子线程执行结束就已经执行结束了,因此子线程根本就没有来得及执行,程序就结束了。

我觉得这里可以理解为如果子线程的资源需要主线程来回收的话,那么主线程就一定要等子线程结束,因为子线程还没用完呢你就不能拿去回收,但是如果子线程资源要自动回收的话,那么主线程就不必等你了。

展开阅读全文
swings_ss关注
swings_ss

41篇文章

排名:千里之外

炸鸡叔关注
炸鸡叔

216篇文章

排名:9000+

grantxx关注
grantxx

84篇文章

排名:千里之外

魏波-关注
魏波-

723篇文章

排名:907

ADGH定制卫衣冬季加绒加厚工作班服连帽外套DIY定做Logo印字1688热销
一款完全免费的炒股软件?市场上的炒股软件是收费的更好一些么?大观
上班的人怎样玩好股票?大观
什么是股票,怎么玩,请高手用通俗易懂的语言解释?大观
你有什么相见恨晚的法语学习方法?大观

没有更多推荐了,返回首页

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!