C 分离的pthread会导致内存泄漏
当终止运行未附加pthreads的进程时,会出现一个错误。然而,分离线程似乎不是一个解决方案。考虑下面的最小例子:C 分离的pthread会导致内存泄漏,c,multithreading,unix,pthreads,pthread-join,C,Multithreading,Unix,Pthreads,Pthread Join,当终止运行未附加pthreads的进程时,会出现一个错误。然而,分离线程似乎不是一个解决方案。考虑下面的最小例子: #include <pthread.h> #include <stdio.h> static void* thread(void* _) { for(;;); return NULL; } int main(void) { pthread_attr_t attr; pthread_attr_init(&attr); pthrea
#include <pthread.h>
#include <stdio.h>
static void* thread(void* _) {
for(;;); return NULL;
}
int main(void) {
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_t tid; pthread_create(&tid, &attr, thread, NULL);
pthread_attr_destroy(&attr);
return 0;
}
我应该担心吗?在实际的程序中,我有几个阻塞线程,因此,就像在最小的示例中一样,我不能真正使用它们
pthread\u join()
。我应该调用pthread\u cancel()
而不是直接调用exit()
吗?从main
返回相当于整个进程的exit
,因此这实际上是终止分离的线程的一种非常粗鲁的方式。当main
函数结束时,您的线程根本没有终止,它只是在exit
机制强制终止时才会终止。因此valgrind缺少线程资源的释放
valgrind告诉您存在内存泄漏这一事实本身不应该让您担心,但您的线程在无法清理和/或完成其任务的情况下被终止这一事实应该让您担心
如果希望在
main
线程结束后继续执行线程,则应通过pthread\u exit
而不是return
终止main。然后由分离的线程决定何时终止自身。它可以在通过原子设置的状态变量或通过互斥/条件机制接收必要的信息时决定是否退出。您应该使用某种“种类”信号机制来通知线程退出,然后等待它们退出。pthread_cancel()是一种“粗鲁”的停止线程的方法,它可能什么也不做(由于线程的当前状态,取消无法执行),或者可能会破坏程序状态。我不认为“资源开始释放到系统中”是指你所想的,从用户空间来衡量这一点是不容易的。(我想到了检查/proc/*
)@antiduh:你如何善意地通知正在进行的线程它应该退出?使用线程关注的标志。实际上,valgrind只是认为存在内存泄漏,可能没有内存泄漏。我克服这个恼人警告的唯一方法是使pthread可连接,当它退出时(在我的例子中是Ctrl-C)——我设置一些“停止”标志(volatile sig_atomic_t类型)并在主线程中执行pthread_join()
。pthread函数不断地在无限循环中检查这个标志,当它被设置时——pthread从无限循环中断并从线程函数返回。一旦完成--pthread_join()
将在主循环中返回,我没有收到来自valgrind的警告。
gcc -pthread c.c
valgrind --leak-check=full a.out
==9341== Command: a.out
==9341==
==9341==
==9341== HEAP SUMMARY:
==9341== in use at exit: 272 bytes in 1 blocks
==9341== total heap usage: 1 allocs, 0 frees, 272 bytes allocated
==9341==
==9341== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1
==9341== at 0x4C2ABB4: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==9341== by 0x4012598: _dl_allocate_tls (dl-tls.c:296)
==9341== by 0x4E3C7B5: pthread_create@@GLIBC_2.2.5 (allocatestack.c:579)
==9341== by 0x400825: main (in /home/witiko/a.out)
==9341==
==9341== LEAK SUMMARY:
==9341== definitely lost: 0 bytes in 0 blocks
==9341== indirectly lost: 0 bytes in 0 blocks
==9341== possibly lost: 272 bytes in 1 blocks
==9341== still reachable: 0 bytes in 0 blocks
==9341== suppressed: 0 bytes in 0 blocks