#include
void* __task(void*arg)
{
return (void*)0;
}
int main(int agrc, char**argv)
{
int i = 0;
pthread_t pid = 0;
int ret = 0;
pthread_attr_t attr;
for(i=0; i<1000000; i++){
pthread_attr_init(&attr);
//
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
//方法1
ret = pthread_create(&pid, &attr, __task, NULL);
//
pthread_detach(pid);
//方法2
//
pthread_join(pid, NULL);
//方法3
if(ret!=0){
printf("failed to create pthread[%d] ret=%d\n", i, ret);
perror("pthread_create");
break;
}
}
}
============================================================
一个没有被分离的线程,在退出时,系统会保留它的虚拟内存,包括他们的堆栈和其他系统资源,这种线程被称为“
僵尸线程”。创建线程时默认是非分离的,或者称为可连接的(joinable)。
大量的僵尸线程,会大量占用系统的内存资源,导致运行异常。
避免僵尸线程实际上就是要考虑如何正确的回收线程资源。
一般来说,有3种常用方法:
方法1:创建线程前,利用pthread_attr_setdetachstate将线程设为detached,这样线程退出时,系统自动回收线程资源。
方法2:创建线程后,用pthread_detach将其设置为detached。
方法3:线程A退出后,线程B调用pthread_join来主动释放线程A的资源。pthread_join可能发生阻塞。
方法4:在线程task中,pthread_detach(pthread_self());
当3种方法都不调用时,上述代码运行中会报错,因为内存不足了:
[lubo@localhost max_threads]$ ./a.out
failed to create pthread[32754] ret=11
pthread_create: Cannot allocate memory
pthread_join的一个经典用法:
void* taskA(void* arg)
{
while(running){
//......
}
}
void stop_task() //线程B如何让线程A退出并释放资源
{
running = 0;
phtread_join(pid, NULL);
}
===============================================================
Linux man page 里有已经说明了这个问题:
When a joinable thread terminates, its memory resources (thread descriptor and stack) are not deallocated until another thread performs pthread_join on it. Therefore,
pthread_join must be called once for each joinable thread created to avoid
memory leaks
.
也就说未分离的线程执行完后如果不join的话,线程的资源会一直得不到释放而导致内存泄漏!