why pthread causes a memory leak

匿名 (未验证) 提交于 2019-12-03 01:10:02

问题:

Whenever I create a pthread, valgrind outputs a memory leak,

For example the below code:

#include  #include  #include    void *timer1_function (void *eit){   (void) eit;     printf("hello world\n");     pthread_exit(NULL); }  int main(void){    pthread_t timer1;    pthread_create( &timer1, NULL, timer1_function,  NULL);  ///////line13    int i=0;    for(i=0;i

valgrind outputs

==1395== HEAP SUMMARY: ==1395==     in use at exit: 136 bytes in 1 blocks ==1395==   total heap usage: 6 allocs, 5 frees, 1,134 bytes allocated ==1395==  ==1395== 136 bytes in 1 blocks are possibly lost in loss record 1 of 1 ==1395==    at 0x402A629: calloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so) ==1395==    by 0x4011304: allocate_dtv (dl-tls.c:297) ==1395==    by 0x4011AAB: _dl_allocate_tls (dl-tls.c:461) ==1395==    by 0x4052470: pthread_create@@GLIBC_2.1 (allocatestack.c:571) ==1395==    by 0x8048566: main (test.c:13) ==1395==  ==1395== LEAK SUMMARY: ==1395==    definitely lost: 0 bytes in 0 blocks ==1395==    indirectly lost: 0 bytes in 0 blocks ==1395==      possibly lost: 136 bytes in 1 blocks ==1395==    still reachable: 0 bytes in 0 blocks ==1395==         suppressed: 0 bytes in 0 blocks 

why pthread_create cause a problem although I was using the man page as reference, and how can I fix it?

回答1:

A thread is an allocated resource and you did not free it before exiting. You should call pthread_join; this would also eliminate the need for your hackish and incorrect sleep loop.

It's possible that even once you fix this, valgrind will still see a "leak", since some implementations of POSIX threads (I'm guessing you're using glibc/NPTL) cache and reuse thread resources rather than freeing them fully. I'm not sure if valgrind works around this or not.



回答2:

I think that valgrind analyzes the state of your program at the time it exits, which is likely before the thread finishes its execution: two microseconds may not be enough to write "Hello, world!\n" to console. Adding a call to pthread_join should fix this leak:

pthread_join(timer1, NULL); 


回答3:

I've seen similar results when I fail to call pthread_join.

When I do call pthread_join, Valgrind will indicate no memory errors or leaks. I've had a clean result using pthread_kill to see if the thread still exists, then calling join to clean up and release resources.

int stop_worker(worker_t *self) {     if (self) {         // signal the thread to quit             // (here using a variable and semaphore)         self->thread_quit=TRUE;         sem_post(&self->sem);          // wait for it to stop         // (could use counter, etc. to limit wait)         int test=0;         while (pthread_kill(self->thread,0) == 0) {             MDEBUG(MD_XF_LOGGER,"waiting for thread to exit...\n",test);             delay_msec(50);         }          // even though thread is finished, need to call join         // otherwise, it will not release its memory (and valgrind indicates a leak)         test=pthread_join(self->thread,NULL);         return 0;                }     return -1; } 


回答4:

memory leak is a result of the fact that if the thread is left running without cancellation , then the corresponding dynamically allocated memory is not freed. Use pthread_cancel() along with pthread_cleanup_push(CleanupHandler, NULL) and pthread_cleanup_pop(0) to do the thread cleanup after cancellation.



回答5:

The leak that shows up is related to the DTV (Dynamic Thread Vector) structure that is allocated in the child thread's local storage (tls).

Using pthread_join() in the main thread (i.e. the thread that spawned the child) will ensure to fix the leak. For use cases where pthread_join() call is not required, calling pthread_detach with child pthread_t ensures the memory is released.

From man for pthread_detach:

The pthread_detach() function marks the thread identified by thread as detached. When a detached thread terminates, its resources are automatically released back to the system without the need for another thread to join with the terminated thread.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!