C/C++:pthread_join()和pthread_detach()的区别
简单来说: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
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
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
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;
}
结果如下
主线程不会等待子线程执行结束就已经执行结束了,因此子线程根本就没有来得及执行,程序就结束了。
我觉得这里可以理解为如果子线程的资源需要主线程来回收的话,那么主线程就一定要等子线程结束,因为子线程还没用完呢你就不能拿去回收,但是如果子线程资源要自动回收的话,那么主线程就不必等你了。
![1.png?p=58&a=386&c=0&k=&d=1&t=3](https://i-blog.csdnimg.cn/blog_migrate/4d5ce3213feb24923686553ddeadc9af.png)
![anonymous-User-img.png](http://g.csdnimg.cn/static/user-img/anonymous-User-img.png)
关于pthread_create()第四个参数的问题
linux下用C开发多线程程序,Linux系统下的多线程遵循POSIX线程接口,称为pthread。 这是百度百科上的定义: #include <pthread.h> int pthread_c 论坛
![feedLoading.gif](https://i-blog.csdnimg.cn/blog_migrate/8d9efd81b3899310987010b538b2b3de.gif)
没有更多推荐了,返回首页