1. 没有pthread_detach导致内存泄漏
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
void doprint(void *arg){
printf("arg=%d\n",*(int *)arg);
pthread_detach(pthread_self());
}
void main (){
pthread_t pid ;
int count = 0;
while(count < 10000){
pthread_create(&pid,NULL,doprint,&count);
usleep(10000);
count++;
}
printf("end count=%d\n",count);
}
PID Vss Rss Pss Uss Swap PSwap USwap ZSwap cmdline
448 1253112K 145028K 52131K 34856K 3820K 1695K 1560K 501K system_server
932 1230132K 132032K 42376K 31248K 2412K 232K 96K 68K com.android.systemui
1098 1177852K 113520K 24575K 10668K 6896K 3345K 2972K 988K com.android.settings
1525 1155976K 109036K 23866K 14320K 2304K 136K 0K 40K com.android.launcher3
876 1171652K 97424K 19977K 12112K 2484K 230K 88K 68K com.android.phone
19161 3123964K 14772K 12736K 12704K 0K 0K 0K 0K ./data/test
896 1157256K 83764K 12699K 6928K 2656K 392K 248K 115K com.android.bluetooth
1550 1122764K 76592K 11347K 6040K 4804K 1106K 708K 327K android.process.media
可以看到test进程,Vss几乎吧3G的用户空间虚拟地址都用完了。
加了pthread_detach之后
20761 4980K 2324K 399K 376K 0K 0K 0K 0K ./data/test
或者在创建线程时,添加属性,用法如下:
5 // 或者创建线程前设置 PTHREAD_CREATE_DETACHED 属性
6 pthread_attr_t attr;
7 pthread_t thread;
8 pthread_attr_init (&attr);
9 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
10 pthread_create (&thread, &attr, &thread_function, NULL);
11 pthread_attr_destroy (&attr);
下面这段转自http://www.hack6.com/html/bc/C/20141106/52232.html
在任何一个时间点上,线程是可结合的(joinable)或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死。在被其他线程回收之前,它的存储器资源(例如栈)是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。
默认情况下,线程被创建成可结合的。为了避免存储器泄漏,每个可结合线程都应该要么被显示地回收,即调用pthread_join;要么通过调用pthread_detach函数被分离。
[cpp]
int pthread_join(pthread_t tid, void**thread_return);
若成功则返回0,若出错则为非零。
int pthread_join(pthread_t tid, void**thread_return);
若成功则返回0,若出错则为非零。 线程通过调用pthread_join函数等待其他线程终止。pthread_join函数分阻塞,直到线程tid终止,将线程例程返回的(void*)指针赋值为thread_return指向的位置,然后回收已终止线程占用的所有存储器资源。[cpp] view plaincopyprint?int pthread_detach(pthread_t tid);
若成功则返回0,若出错则为非零。
int pthread_detach(pthread_t tid);
若成功则返回0,若出错则为非零。
pthread_detach用于分离可结合线程tid。线程能够通过以pthread_self()为参数的pthread_detach调用来分离它们自己。
如果一个可结合线程结束运行但没有被join,则它的状态类似于进程中的Zombie Process,即还有一部分资源没有被回收,所以创建线程者应该调用pthread_join来等待线程运行结束,并可得到线程的退出代码,回收其资源。
由于调用pthread_join后,如果该线程没有运行结束,调用者会被阻塞,在有些情况下我们并不希望如此。例如,在Web服务器中当主线程为每个新来的连接请求创建一个子线程进行处理的时候,主线程并不希望因为调用pthread_join而阻塞(因为还要继续处理之后到来的连接请求),这时可以在子线程中加入代码
pthread_detach(pthread_self())
或者父线程调用
pthread_detach(thread_id)(非阻塞,可立即返回)
这将该子线程的状态设置为分离的(detached),如此一来,该线程运行结束后会自动释放所有资源