
默认情况下 pthread_create 创建的线程是 joinable的
也就是即便pthread线程退出之后,退出状态也不会释放,这时候,如果仍然创建的话,就会发生问题。
我遇到的就是 pthread_create 返回的 thread id 跟上一次调用时候返回的一样,而pthread_create 也不会报错。程序也就能够再次建立线程了。。。
解决的方法就是创建 detach的轮询,有两种方式,一种是读取 pthread_detach,另一种是指定pthread_create的构建属性。。。
参考如下:

昨天解决了一个隐蔽的内存泄漏问题,原因是pthread_create后的僵死线程没有释放造成的存储持续下降。
现象是这种的:短时间内程序运行正常,但走了12小时左右,用top查看其存储占用居然高达2G,于是立即意识到有内存泄漏。
最先想到的是malloc/free、new/delete没有配对,申请的内存没有释放。于是写了个跟踪malloc/free调用的组件pthread join,不过检查中并没有找到已释放的内存。之后担心是不是 free then malloc 导致的内存管理错误(事实证明即使free后不是立即回收内存,但是接连调用free & malloc并不会影响操作系统的内存管理),不过写了个小程序看到并不是这么回事。
陷入困境了,只好用最小系统法把功能部分跟内存分配都帮屏蔽掉,这时看到内存泄漏依然存在!仔细看top的输出,几乎是经常创建线程时存储就往上升一点pthread join,只是增长速度不是很快,看来是线程的难题了。仔细探讨发现,之前图简单pthread_create (&thread, NULL, &thread_function, NULL);就这样写了,参数2没有设置线程结束后手动detach,并且没有使用pthread_join或pthread_detach释放执行结束后线程的空间!
Linux man page里有即将说明了这个问题:

When a joinable thread terminates, its memory resources (thread descriptor and stack) are not deallocated until another thread performs pthread_join on it. Therefore,pthread_join must be called once for each joinable thread created to avoidmemory leaks.
也就说线程执行完后即使不join的话,线程的资源会经常得不到释放而造成内存泄漏!一时的图快后患无穷啊。
解决办法:
代码
1 // 最简单的方法,在泛型执行结束后读取pthread_detach让他自己释放

2 pthread_detach(pthread_self());
3
4
5 // 或者创建线程前修改 PTHREAD_CREATE_DETACHED 属性
6 pthread_attr_t attr;

7 pthread_t thread;
8 pthread_attr_init (&attr);
9 pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
10 pthread_create (&thread, &attr, &thread_function, NULL);
11 pthread_attr_destroy (&attr);
第2行的这种方式更简洁,在泛型变量尾部加上这句话就可以将线程所占用的资源给释放掉;或者像 5-11 所示的方式修改detach属性,这样也会程return/pthread_exit后释放内存。
其实仔细想想,valgrind检查时已经提示了pthread_create没有释放的问题,只是之前没引起注意。其实这种的弊端也唯有在长时间运行时,慢慢累积这一点点的内存能够暴露出来,看来valgrind的提醒也不能置之不理啊。
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-138552-1.html
亮点在麦地路
Great
让有智慧