内存泄漏与pthread_cancel()本身

时间:2012-03-18 22:50:36

标签: c pthreads

我创建了一个JOINABLE线程,后来在程序结束时取消了它,例如

rc2 = pthread_attr_init(&attr);
ERR_IF( rc2 != 0 );
rc2 = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
ERR_IF( rc2 != 0 );
rc2 = pthread_create(&destroy_thread, &attr, destroy_expired_sessions, NULL);
ERR_IF( rc2 != 0 );
...
rc2 = pthread_cancel(destroy_thread);
ERR_IF( rc2 != 0 );
rc2 = pthread_join(destroy_thread, &status);
ERR_IF( rc2 != 0 || (int *)status != PTHREAD_CANCELED);

然而,pthread_cancel()存在内存泄漏,由valgrind分析:

==17583== 28 bytes in 1 blocks are still reachable in loss record 1 of 1
==17583==    at 0x4006878: malloc (in /m/mls/pkg/trees/2008Q3/ix86-Linux-RHEL5/lib/valgrind/x86-linux/vgpreload_memcheck.so)
==17583==    by 0x79FAC1: _dl_map_object_deps (in /lib/ld-2.5.so)
==17583==    by 0x7A4A67: dl_open_worker (in /lib/ld-2.5.so)
==17583==    by 0x7A0DA5: _dl_catch_error (in /lib/ld-2.5.so)
==17583==    by 0x7A43F1: _dl_open (in /lib/ld-2.5.so)
==17583==    by 0x8BF2E1: do_dlopen (in /lib/libc-2.5.so)
==17583==    by 0x7A0DA5: _dl_catch_error (in /lib/ld-2.5.so)
==17583==    by 0x8BF494: __libc_dlopen_mode (in /lib/libc-2.5.so)
==17583==    by 0x9527D6: pthread_cancel_init (in /lib/libpthread-2.5.so)
==17583==    by 0x94EC1B: pthread_cancel (in /lib/libpthread-2.5.so)
==17583==    by 0x80860CF: authDeinit (authAPI.c:1545)
==17583==    by 0x807F280: main (test_sessionList.c:124)
==17583== 
==17583== LEAK SUMMARY:
==17583==    definitely lost: 0 bytes in 0 blocks.
==17583==      possibly lost: 0 bytes in 0 blocks.
==17583==    still reachable: 28 bytes in 1 blocks.
==17583==         suppressed: 0 bytes in 0 blocks.

这似乎是函数pthread_cancel()本身的缺陷。看起来它是malloc()'ed ed some memory但后来没有释放()。有没有办法避免内存泄漏?

2 个答案:

答案 0 :(得分:3)

这就是pthread_cancel()的工作方式。调用时,它会调用pthread_cancel_init()以确保动态链接多个项目(使用dlopen()dlsym()的等效项)。这些动态链接的函数/符号旨在用于该进程的剩余生命周期。

所以这不是泄漏,因为某些东西已经失去了 - 而是它被装载并且意图保持活力。

我建议将valgrind配置为在可能的情况下忽略此分配。

答案 1 :(得分:0)

强行终止线程永远不是一个好主意。最好提出一种干净的方式来通知线程自己退出(并自己进行资源清理)。然后调用pthread_join完成清理。