即使状态已分离,pthread 中的内存泄漏 [英] Memory leaks in pthread even if the state is detached

查看:80
本文介绍了即使状态已分离,pthread 中的内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习 pthreads 编程.

I am learning pthreads programming.

我了解到线程有两种状态:1. 可连接2. 可拆卸

I understood that there are two states of thread: 1. Joinable 2. Detachable

Joinable 的情况下,需要调用 pthread_join 来释放资源(栈),而 detached 的情况下不需要调用 pthread_join,资源会在线程退出时释放.

In case of Joinable, we need to call pthread_join to free the resources(stack), whereas in case of detached there is no need to call pthread_join and the resources will be freed on thread exit.

我写了一个示例程序来观察行为

I wrote a sample program to observe the behavior

#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>

void *threadFn(void *arg)
{

 pthread_detach(pthread_self());
 sleep(1);
 printf("Thread Fn\n");
 pthread_exit(NULL);
}

int main(int argc, char *argv[])
{

 pthread_t tid;
 int ret = pthread_create(&tid, NULL, threadFn, NULL);

 if (ret != 0) {
  perror("Thread Creation Error\n");
  exit(1);
 }
 printf("After thread created in Main\n");
 pthread_exit(NULL);
}

当我尝试使用 valgrind 检查任何内存泄漏时,它给了我 272 字节的泄漏.你能告诉我为什么这里会发生泄漏吗.

When i try to check any mem leaks with valgrind it gave me leaks of 272 bytes. Can you show me why is the leak happening here.

$valgrind --leak-check=full ./app
==38649== 
==38649== HEAP SUMMARY:
==38649==     in use at exit: 272 bytes in 1 blocks
==38649==   total heap usage: 7 allocs, 6 frees, 2,990 bytes allocated
==38649== 
==38649== 272 bytes in 1 blocks are possibly lost in loss record 1 of 1
==38649==    at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==38649==    by 0x40134A6: allocate_dtv (dl-tls.c:286)
==38649==    by 0x40134A6: _dl_allocate_tls (dl-tls.c:530)
==38649==    by 0x4E44227: allocate_stack (allocatestack.c:627)
==38649==    by 0x4E44227: pthread_create@@GLIBC_2.2.5 (pthread_create.c:644)
==38649==    by 0x108902: main (2.c:18)
==38649== 
==38649== LEAK SUMMARY:
==38649==    definitely lost: 0 bytes in 0 blocks
==38649==    indirectly lost: 0 bytes in 0 blocks
==38649==      possibly lost: 272 bytes in 1 blocks
==38649==    still reachable: 0 bytes in 0 blocks
==38649==         suppressed: 0 bytes in 0 blocks
==38649== 
==38649== For counts of detected and suppressed errors, rerun with: -v
==38649== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

推荐答案

您的预期是正确的,即调用 pthread_exit 后主线程中不应该有任何泄漏.

Your expectation is correct that there shouldn't be any leaks in main thread once you call pthread_exit.

但是,您观察到的是您正在使用的实现的一个怪癖(可能是 glibc)——pthreads 库(glibc 实现)重新使用最初为线程分配的堆栈——就像一个缓存,以便之前分配的堆栈可以尽可能重复使用.

However, what you observe is a quirk of the implementation you're using (which is likely to be glibc) - pthreads library (glibc implementation) re-uses the initially allocated stack for threads - like a cache so that previously allocated stacks can be re-used whenever possible.

Valgrind 只是简单地报告它看到"的内容(分配了但未取消分配的内容).但这并不是真正的泄漏,因此您无需担心.

Valgrind simply reports what it "sees" (something was allocated but not de-allocated). But it's not a real leak, so you don't need to worry about this.

如果您反转"逻辑(主线程作为最后一个线程退出),那么您将不会看到泄漏,因为最初分配的堆栈空间已被主线程正确释放.但是这种泄漏在任何情况下都不是真正的泄漏,您可以放心地忽略它.

If you "reverse" the logic (main thread exits as the last thread) then you wouldn't see leaks because the initially allocated stack space is properly free'd by the main thread. But this leak isn't a real leak in any case and you can safely ignore this.

您还可以设置抑制文件 这样 Valgrind 就不会抱怨这个(这是通知 Valgrind 我知道这不是真正的泄漏,所以不要报告这个"),例如:

You can also setup a suppression file so that Valgrind doesn't complain about this (which is to inform Valgrind that "I know this isn't not real leak, so don't report this"), such as:

{
   Pthread_Stack_Leaks_Ignore
   Memcheck:Leak
   fun:calloc
   fun:allocate_dtv
   fun:_dl_allocate_tls
   fun:allocate_stack
   fun:pthread_create*

}

这篇关于即使状态已分离,pthread 中的内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆