C++ 使用 pthread_create 时的 valgrind 内存泄漏错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5610677/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 18:31:08  来源:igfitidea点击:

valgrind memory leak errors when using pthread_create

c++memory-leakspthreadsvalgrind

提问by lim

I'm writing a program using the pthread library. When I run my program with the command valgrind --leak-check=full, I get the following errors description:

我正在使用 pthread 库编写程序。当我使用命令运行我的程序时valgrind --leak-check=full,我收到以下错误描述:

==11784==  
==11784== **HEAP SUMMARY:**  
==11784==     in use at exit: 4,952 bytes in 18 blocks  
==11784==   total heap usage: 1,059 allocs, 1,041 frees, 51,864 bytes allocated  
==11784==  
==11784== **288 bytes** in 1 blocks are possibly lost in loss record 2 of 3  
==11784==    at 0x4C2380C: calloc (vg_replace_malloc.c:467)  
==11784==    by 0x4010D2E: _dl_allocate_tls (dl-tls.c:300)  
==11784==    by 0x55DC218: **pthread_create**@@GLIBC_2.2.5 (allocatestack.c:570)  
==11784==    by 0x401BC0: initdevice(char*) (in /a/fr-01/vol/home/stud/lim/workspace  /Ex3/l)  
==11784==    by 0x406D05: main (in /a/fr-01/vol/home/stud/lim/workspace/Ex3/l)  
==11784==  
==11784== **4,608 bytes** in 16 blocks are possibly lost in loss record 3 of 3  
==11784==    at 0x4C2380C: calloc (vg_replace_malloc.c:467)  
==11784==    by 0x4010D2E: _dl_allocate_tls (dl-tls.c:300)  
==11784==    by 0x55DC218: **pthread_create**@@GLIBC_2.2.5 (allocatestack.c:570)    
==11784==    by 0x40268F: write2device(char*, int) (in /a/fr-01/vol/home/stud/lim/workspace/Ex3/l)  
==11784==    by 0x406D7B: main (in /a/fr-01/vol/home/stud/lim/workspace/Ex3/l)  
==11784==  
==11784== **LEAK SUMMARY:**  
==11784==    definitely lost: 0 bytes in 0 blocks  
==11784==    indirectly lost: 0 bytes in 0 blocks  
==11784==      possibly lost: 4,896 bytes in 17 blocks  
==11784==    still reachable: 56 bytes in 1 blocks  
==11784==         suppressed: 0 bytes in 0 blocks  
==11784== Reachable blocks (those to which a pointer was found) are not shown.  
==11784== To see them, rerun with: --leak-check=full --show-reachable=yes  
==11784==  
==11784== For counts of detected and suppressed errors, rerun with: -v  
==11784== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)  


Every time I call pthread_create, with a certain function - I call the function pthread_exitin the end of the function. So, after verifying this is not the problem, what could be the problem?

每次我pthread_create用某个函数调用时 - 我在函数pthread_exit的末尾调用该函数。那么,在验证这不是问题之后,可能是什么问题?

回答by Alok Save

A thread's resources are not immediately released at termination, unless the thread was created with the detach stateattribute set to PTHREAD_CREATE_DETACHED, or if pthread_detachis called for its pthread_t.

线程的资源不会在终止时立即释放,除非创建线程时将detach state属性设置为 PTHREAD_CREATE_DETACHED,或者如果pthread_detach为其调用pthread_t.

An undetached thread will remain terminated state until its identifier is passed to pthread_joinor pthread_detach.

未分离的线程将保持终止状态,直到将其标识符传递给pthread_joinpthread_detach

To sum it up, you have three options:

总结一下,你有三个选择:

  1. create your thread with detached attribute set(PTHREAD_CREATE_DETACHED attribute)
  2. Detach your thread after creation (by calling pthread_detach), or
  3. Join with the terminated threads to recycle them (by calling pthread_join).
  1. 创建具有分离属性集的线程(PTHREAD_CREATE_DETACHED 属性)
  2. 创建后分离您的线程(通过调用pthread_detach),或
  3. 加入终止的线程以回收它们(通过调用pthread_join)。

Hth.

嗯。

回答by micha

when not working with joinable threads the exiting thread needs to call pthread_detach(pthread_self())in order to release all its resources.

当不使用可连接线程时,退出线程需要调用pthread_detach(pthread_self())以释放其所有资源。

回答by sehe

You can make the thread in detached stateto avoid the memory leak if the thread should not be joined (or just expires on it's own).

如果线程不应加入(或仅自行过期),您可以使线程处于分离状态以避免内存泄漏。

To explicitly create a thread as joinable or detached, the attr argument in the pthread_create() routine is used. The typical 4 step process is:

要显式创建可连接或分离的线程,请使用 pthread_create() 例程中的 attr 参数。典型的 4 步过程是:

  • Declare a pthread attribute variable of the pthread_attr_tdata type
  • Initialize the attribute variable with pthread_attr_init()
  • Set the attribute detached status with pthread_attr_setdetachstate()
  • When done, free library resources used by the attribute with pthread_attr_destroy()
  • 声明一个pthread_attr_t数据类型的pthread属性变量
  • 初始化属性变量 pthread_attr_init()
  • 设置属性分离状态 pthread_attr_setdetachstate()
  • 完成后,释放属性使用的库资源 pthread_attr_destroy()

回答by Kyrol

In addition to the correct answers given you by other users, I suggest you to read this:

除了其他用户给您的正确答案外,我建议您阅读以下内容:

Tracking down a memory leak in multithreaded C application

跟踪多线程 C 应用程序中的内存泄漏

回答by Aaron He

Please note that the default pthread_create behavior is "joinable" NOT DETACHED. Therefore some OS resources would still remain in the process after pthread finished, which would result in zombie pthread and leads to increased VIRTUAL/resident memory usage.

请注意,默认的 pthread_create 行为是“joinable” NOT DETACHED。因此,一些操作系统资源在 pthread 完成后仍会保留在进程中,这将导致僵尸 pthread 并导致虚拟/常驻内存使用量增加。

The four solution @sehe mentioned would fix this problem.

@sehe 提到的四个解决方案可以解决这个问题。

However if you thread is a long-standing one, this might not be really needed. for example, if the pthread lives through the whole life of the process.

但是,如果您的线程是一个长期存在的线程,则可能不需要这样做。例如,如果 pthread 贯穿进程的整个生命周期。