Linux的线程的创建必然会伴随着内存空间的分配,而当线程函数执行完毕时,线程空间同样也不会被自动收回。特别是,Linux线程的销毁和进程也不一样,即使主函数结束,如果不主动回收,线程空间也不会被释放。类似于永远不能被回收的僵尸进程,我们姑且叫这种线程为僵尸线程吧。本文就是介绍回收这种僵尸线程的资源的两种方法。
方法一:利用pthread_join()函数。
这个函数在之前的文章《利用pthread_join函数等待线程结束并获取线程函数返回值》中已经介绍过,它的第一个功能就是会阻塞等待子线程执行结束,另一个功能就是回收线程结束后的资源。由于介绍过,不再赘述,现在只简单回顾下其用法,其原型如下:
#include <pthread.h>
int pthread_join(pthread_t thread, void **retval);
参数:
thread是要等待的线程的ID。
retval是一个二级指针,指向线程函数的返回值(线程函数返回void*)
返回值:
如果函数执行成功返回0,否则会返回一个错误码。
方法二:利用pthread_detach()函数
其函数原型如下:
#include <pthread.h>
int pthread_detach(pthread_t thread);
pthread_detach()也可以回收线程的资源。但是与pthread_join()不同,该函数不是阻塞函数,它只有一个参数为线程ID。函数成功执行时返回0,发生错误时返回错误码。下面是调用pthread_deatch()的一个例子:
#include<stdio.h>
#include<pthread.h>
int flag=0;
void* pthread_main()
{
int i=0;
for(i=0;i<5;i++)
{
puts("pthread_main called...");
sleep(1);
}
flag=1;
}
int main()
{
pthread_t tid;
pthread_create(&tid,NULL,(void*)pthread_main,NULL);
pthread_detach(tid);
while(!flag)
{
sleep(1);
puts("waiting child thread edned!");
}
return 0;
}
其实代码的原理很简单,在第4行定义一个标志flag=0,在线程函数中不断的打印输出"pthread_main called..."信息,线程函数结束时把flag置1表示线程已经结束。而在主函数中第20行通过pthread_detach()将线程ID注册,表明线程结束后线程的资源将会被操作系统回收。由于pthread_deach()不是阻塞的,代码会执行下去。执行到21行开始的while循环,不断检测flag是否为1,若为1了就退出循环,主函数结束。
最后展示下程序的运行结果:
[Hyman@Hyman-PC operator]$ gcc deatchts.c -lpthread
[Hyman@Hyman-PC operator]$ ./a.out
pthread_main called...
waiting child thread edned!
pthread_main called...
waiting child thread edned!
pthread_main called...
waiting child thread edned!
pthread_main called...
waiting child thread edned!
pthread_main called...
waiting child thread edned!
waiting child thread edned!
Github位置:
https://github.com/HymanLiuTS/NetDevelopment
克隆本项目:
Git clone git@github.com:HymanLiuTS/NetDevelopment.git
获取本文源代码:
git checkout NL41