我有一个如下定义的可连接pthread运行器函数:
void *sumOfProducts(void *param) { ... pthread_exit(0); }
该线程应该加入主线程。
每当我通过Valgrind运行程序时,都会出现 以下泄漏 :
LEAK SUMMARY: definitely lost: 0 bytes in 0 blocks indirectly lost: 0 bytes in 0 blocks possibly lost: 0 bytes in 0 blocks still reachable: 968 bytes in 5 blocks suppressed: 0 bytes in 0 blocks ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 15 from 10)
我检查了手册页中的pthread,其中说:
The new thread terminates in one of the following ways: * It calls pthread_exit(3), specifying an exit status value that is available to another thread in the same process that calls pthread_join(3). * It returns from start_routine(). This is equivalent to calling pthread_exit(3) with the value supplied in the return statement. * It is canceled (see pthread_cancel(3)). * Any of the threads in the process calls exit(3), or the main thread performs a return from main(). This causes the termination of all threads in the process.
奇迹般地,当我用return语句替换pthread_exit()时, 泄漏消失了 。
return(NULL);
我的实际问题有三点:
下面的最小测试用例展示了您描述的行为:
#include <pthread.h> #include <unistd.h> void *app1(void *x) { sleep(1); pthread_exit(0); } int main() { pthread_t t1; pthread_create(&t1, NULL, app1, NULL); pthread_join(t1, NULL); return 0; }
valgrind --leak-check=full --show- reachable=yes显示了从调用的函数分配的5个块,这些块pthread_exit()未释放,但在进程退出时仍可访问。如果将pthread_exit(0);替换为return 0;,则不会分配5个块。
valgrind --leak-check=full --show- reachable=yes
pthread_exit()
pthread_exit(0);
return 0;
但是,如果测试创建和联接大量线程,则会发现退出时使用的未释放内存量 不会 增加。这以及它仍然可以访问的事实,表明您只是看到glibc实现的怪异之处。几个glibc函数malloc()在第一次调用时分配内存,它们在剩余的进程生命周期中一直分配。glibc无需在进程退出时释放该内存,因为它知道该进程无论如何都将被拆除- 这只会浪费CPU周期。
malloc()