分离的pthread会导致内存泄漏

时间:2014-01-02 22:46:14

标签: c multithreading unix pthreads pthread-join

当使用未分离的pthreads终止进程时,有一个known memory leak。但是,分离线程似乎不是一个解决方案。请考虑以下最小示例:

#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;
}

创建具有无限循环的分离线程,并立即终止该进程。根据{{​​1}},一旦整个过程终止,线程的资源应自动释放回系统。然而,这显然不是正在发生的事情:

pthread_detach(3)

我应该担心吗?在实际的程序中,我有几个阻塞线程,所以,就像在最小的例子中,我真的不能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 与它们。我应该直接拨打pthread_join()而不是pthread_cancel()吗?

1 个答案:

答案 0 :(得分:8)

main返回相当于整个过程的exit,所以这实际上是一种终止分离线程的粗鲁方式。当main函数结束时,您的线程根本没有终止,只有在exit机制强制它时才会终止。所以valgrind错过了线程资源的释放。

valgrind告诉你内存泄漏的事实不应该让你自己担心,但你的线程终止而不能清理和/或完成任务的事实应该让你担心。

如果您希望在main主题结束后继续执行您的主题,则应该pthread_exit而不是return终止主要主题。然后由你的分离线程决定何时终止自己。它可以通过原子设置的状态变量或通过互斥/条件机制接收必要的信息来决定。