使用 pthread_create 时出现 valgrind 内存泄漏错误
Posted
技术标签:
【中文标题】使用 pthread_create 时出现 valgrind 内存泄漏错误【英文标题】:valgrind memory leak errors when using pthread_create 【发布时间】:2011-08-02 09:54:21 【问题描述】:我正在使用 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)
每次我用某个函数调用pthread_create
时,我都会在函数末尾调用函数pthread_exit
。那么,在验证这不是问题之后,可能是什么问题?
【问题讨论】:
那么您是否尝试编写一个只执行 pthread_create/pthread_exit (+join) 并在 valgrind 下运行的程序? 尝试使用“--leak-check=full --show-reachable=yes”运行它。猜测是重复的结构可能不会被删除。但是没有代码自己测试它我不能说太多。 您是否加入了pthread_join
的线程?否则会发生泄漏。
【参考方案1】:
如果线程不应该加入(或只是自行过期),您可以创建线程in detached state 以避免内存泄漏。
声明一个要显式创建可连接或分离的线程,使用 pthread_create() 例程中的 attr 参数。典型的 4 步流程是:
pthread_attr_t
数据类型的pthread属性变量
用pthread_attr_init()
初始化属性变量
用pthread_attr_setdetachstate()
设置属性分离状态
完成后,释放pthread_attr_destroy()
属性使用的库资源
【讨论】:
我已经检查了一下,发现当我调用 'pthread_detach' 而不是 pthread_exit - 没有像我提到的那样的内存泄漏问题更多。这样做可以不写'pthread_exit'吗? 手册页上写着:The pthread_join() or pthread_detach() functions should eventually be called for every thread that is created so that storage associated with the thread may be reclaimed
我已经阅读了这个手册页。它仍然没有回答我的问题。
啊,对不起:An implicit call to pthread_exit() is made when a thread other than the thread in which main() was first invoked returns from the start routine that was used to create it. The function's return value shall serve as the thread's exit status
你可以不说【参考方案2】:
线程的资源不会在终止时立即释放,除非
创建线程时将detach state
属性设置为
PTHREAD_CREATE_DETACHED
,或者如果需要 pthread_detach
它的pthread_t
。
未分离的线程将保持终止状态,直到其标识符传递给pthread_join
或pthread_detach
。
总结起来,你有三个选择:
-
使用分离的属性集(PTHREAD_CREATE_DETACHED 属性)创建您的线程
创建后分离线程(通过调用
pthread_detach
),或
加入已终止的线程以回收它们(通过调用pthread_join
)。
Hth.
【讨论】:
请看我的问题***.com/questions/41057644/…。这个答案很有用,但对我没有帮助。【参考方案3】:除了其他网友给你的正确答案,我建议你阅读以下内容:
Tracking down a memory leak in multithreaded C application
【讨论】:
【参考方案4】:当不使用可连接线程时,退出线程需要调用pthread_detach(pthread_self())
为了释放它的所有资源。
【讨论】:
pthread_detach(pthread_self()) 对我有用(阻止 valgrind 报告内存泄漏)。这种方法也很方便,因为当动态创建线程时,要跟踪所有启动的线程并执行 pthread_join() 相当困难。 这里有些混乱。线程可以是可连接的,也可以是分离的。pthread_detach
分离线程是错误的,因此只能为可连接线程调用。当“不使用可连接线程”时,顶层函数的简单返回会释放所有资源。【参考方案5】:
请注意,默认的 pthread_create 行为是“可连接的”而不是分离的。 因此,在 pthread 完成后,一些 OS 资源仍会保留在进程中,这将导致僵尸 pthread 并导致 VIRTUAL/resident 内存使用量增加。
@sehe 提到的四个解决方案可以解决这个问题。
但是,如果您的线程是一个长期存在的线程,那么这可能并不是真正需要的。 例如,如果 pthread 在进程的整个生命周期中都存在。
【讨论】:
以上是关于使用 pthread_create 时出现 valgrind 内存泄漏错误的主要内容,如果未能解决你的问题,请参考以下文章
在 TCP 服务器中使用 pthread_create 时出现错误 11
Ubuntu使用多线程cmake时出现undefined reference to `pthread_create'
在 Java 对象的 Kotlin 中设置属性时出现奇怪的“无法重新分配 Val”错误
在 Java 对象的 Kotlin 中设置属性时出现奇怪的“无法重新分配 Val”错误
Debian下undefined reference to ‘pthread_create’问题解决
[Android]异常10-java.lang.OutOfMemoryError pthread_create (1040KB stack) failed: Try again