2012年(82)
分类: C/C++
2012-08-18 16:45:38
用top发现virt的使用量一直在涨。于是可以断定有内存泄漏了,经过排查,最终确定原因出在多线程的问题上:
代码如下:
1 2 3 4 5 6 | pthread_t thread_id; int ret=pthread_create(&thread_id, NULL, flush_thread_work, (void*)&m_sql_client); if(ret!=0){ APPSCORE_ERROR("Thread creation failed:%d",ret); return ret; } |
在flush_thread_work函数内部:
1 2 3 4 5 | void* flush_thread_work(void* args) { //....do something return NULL; } |
代码中启动了一个线程之后,主进程就继续执行,任由新线程自生自灭了(没有调用thread_join),而主进程每隔一段时间就会拉起这样一个线程来做一些数据落地的事情。
这样的写法实际上是会造成内存泄漏的.
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 avoid memory leaks.
也就说线程执行完后如果不join的话,线程的资源会一直得不到释放而导致内存泄漏!
解决方法有两种:
a.在线程执行的函数内手工释放
1 2 3 4 5 6 | void* flush_thread_work(void* args) { //....do something pthread_detach(pthread_self()); return NULL; } |
b.在线程启动时,设置线程的PTHREAD_CREATE_DETACHED属性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | pthread_attr_t attr; pthread_attr_init (&attr); pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED); int ret=pthread_create(&thread_id, &attr, flush_thread_work, (void*)&m_sql_client); if(ret!=0){ //记住attr也要析构,否则又是一个内存泄漏 pthread_attr_destroy (&attr); APPSCORE_ERROR("Thread creation failed:%d",ret); return ret; } //记住attr也要析构,否则又是一个内存泄漏 pthread_attr_destroy (&attr); |