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