我写了一个简单的线程程序:
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdint.h>
#define THREADS 5
void* HelloWorld(void *t)
{
printf("Thread ID #%lu: (%lu) Hello World !!\n", pthread_self(), (unsigned long)t);
return NULL;
}
int main()
{
pthread_t thread[THREADS];
uint32_t i;
int err;
for(i = 0; i < THREADS; ++i)
{
err = pthread_create(&thread[i], NULL, &HelloWorld, (void*)(unsigned long long)i);
if(err != 0)
{
printf("Error %d: Thread %d Creation Unsuccessful !!\n", err, i);
}
printf("Thread %lu in main()\n", pthread_self());
}
/*
for(i = 0; i < THREADS; ++i)
{
pthread_join(thread[i], NULL); // Error checking implemented
}
*/
return 0;
}
但是使用 valgrind 作为:
valgrind --tool=memcheck --leak-check=full --show-reachable=yes ./hello
它显示内存使用/泄漏的相同输出,无论是否在程序中使用pthread_join()
。
请在阅读here时解释此行为:
最终应为每个使用detachstate属性设置为PTHREAD_CREATE_JOINABLE创建的线程调用pthread_join()或pthread_detach()函数,以便可以回收与该线程关联的存储。
如果我不致电pthread_join()
答案 0 :(得分:1)
根据我的理解,提出了两个问题。一个是valgrind
报告带有或不带pthread_join()
调用的内存泄漏的原因,另一个是调用pthread_join()
如果它实际上没有释放任何内存而回收存储的原因。
这两个问题的一个可能的解释是,在调用pthread_join()
之后,您的线程库实际上并没有释放任何内存,而是将已分配的资源放入“可用,如果我最终创建另一个线程未来的“容器。让我们称该容器为池。对pthread_create()
的下一次调用可以重用池中的任何资源。如果池为空,则分配新内存。
不调用pthread_join()
,与退出线程关联的任何资源都不会返回到池中。因此,这些资源将保持不可用,池保持为空,因此新的pthread_create()
将为线程创建请求分配更多资源。
这意味着pthread_join()
根本不一定释放任何内存。它可以简单地将收集的资源放入由线程库维护的池中。因此,无论是否调用pthread_join()
,valgrind
都会显示相同数量的“泄露”内存。但是,pthread_join()
回收了内存,因为它被放置在池中,以便将来调用pthread_create()
。