为什么使用 pthread_exit会有内存泄露呢?
在进行线程编程时如果使用 pthread_exit函数会有内存泄露,代码如下:
- C/C++ code
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h> pthread_t tid1, tid2;void * tret; void * thr_fn1(void * arg){ sleep(1);//睡眠一秒,等待TID2结束。 pthread_join(tid2, &tret);//tid1一直阻塞,等到tid2的退出,获得TID2的退出码 printf("thread 2 exit code %d\n", (int)tret); printf("thread 1 returning\n"); return((void *)2);}void * thr_fn2(void * arg){ printf("thread 2 exiting\n"); [color=#FF0000]pthread_exit((void *)3);[/color]}int main(void){ int err; err = pthread_create(&tid1, NULL, thr_fn1, NULL); if (err != 0) printf("can't create thread 1\n"); err = pthread_create(&tid2, NULL, thr_fn2, NULL); if (err != 0) printf("can't create thread 2\n"); err = pthread_join(tid1, &tret);//主线程一直阻塞,等待TID1的返回。 if (err != 0) printf("can't join with thread 1\n"); printf("thread 1 exit code %d\n", (int)tret); exit(0);}
检查内存信息如下:
==29579== Memcheck, a memory error detector.
==29579== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==29579== Using LibVEX rev 1658, a library for dynamic binary translation.
==29579== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==29579== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==29579== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==29579== For more details, rerun with: -v
==29579==
thread 2 exiting
thread 2 exit code 3
thread 1 returning
thread 1 exit code 2
==29579==
==29579== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 14 from 1)
==29579== malloc/free: in use at exit: 912 bytes in 5 blocks.
==29579== malloc/free: 7 allocs, 2 frees, 1,184 bytes allocated.
==29579== For counts of detected errors, rerun with: -v
==29579== searching for pointers to 5 not-freed blocks.
==29579== checked 64,232 bytes.
==29579==
==29579== LEAK SUMMARY:
==29579== definitely lost: 0 bytes in 0 blocks.
==29579== possibly lost: 0 bytes in 0 blocks.
==29579== still reachable: 912 bytes in 5 blocks.
==29579== suppressed: 0 bytes in 0 blocks.
==29579== Reachable blocks (those to which a pointer was found) are not shown.
==29579== To see them, rerun with: --show-reachable=yes
但是如果将上述代码的 pthread_exit((void *)3);改为return((void *)3);就不会出现内存泄露现象了
代码如下:
- C/C++ code
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <pthread.h> pthread_t tid1, tid2;void * tret; void * thr_fn1(void * arg){ sleep(1);//睡眠一秒,等待TID2结束。 pthread_join(tid2, &tret);//tid1一直阻塞,等到tid2的退出,获得TID2的退出码 printf("thread 2 exit code %d\n", (int)tret); printf("thread 1 returning\n"); return((void *)2);}void * thr_fn2(void * arg){ printf("thread 2 exiting\n"); [color=#FF0000] return((void *)3);[/color]}int main(void){ int err; err = pthread_create(&tid1, NULL, thr_fn1, NULL); if (err != 0) printf("can't create thread 1\n"); err = pthread_create(&tid2, NULL, thr_fn2, NULL); if (err != 0) printf("can't create thread 2\n"); err = pthread_join(tid1, &tret);//主线程一直阻塞,等待TID1的返回。 if (err != 0) printf("can't join with thread 1\n"); printf("thread 1 exit code %d\n", (int)tret); exit(0);}
内存检查信息如下:
==29601== Memcheck, a memory error detector.
==29601== Copyright (C) 2002-2006, and GNU GPL'd, by Julian Seward et al.
==29601== Using LibVEX rev 1658, a library for dynamic binary translation.
==29601== Copyright (C) 2004-2006, and GNU GPL'd, by OpenWorks LLP.
==29601== Using valgrind-3.2.1, a dynamic binary instrumentation framework.
==29601== Copyright (C) 2000-2006, and GNU GPL'd, by Julian Seward et al.
==29601== For more details, rerun with: -v
==29601==
thread 2 exiting
thread 2 exit code 3
thread 1 returning
thread 1 exit code 2
==29601==
==29601== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 13 from 1)
==29601== malloc/free: in use at exit: 0 bytes in 0 blocks.
==29601== malloc/free: 2 allocs, 2 frees, 272 bytes allocated.
==29601== For counts of detected errors, rerun with: -v
==29601== All heap blocks were freed -- no leaks are possible.
这究竟是什么原因呢?网上找了很久也没有查到合适的解释,请高手们指教!
[解决办法]
线程本来就不可以用pthread_exit这类方法自杀的。
[解决办法]
#include <pthread.h>
int pthread join(pthread t tid, void **thread return);
returns: 0 if OK, non-zero on error
The pthread join function blocks until thread tid terminates, assigns the (void *) pointer returned by the thread routine to the location pointed to by thread return, and then reaps any memory resources held by the terminated thread.