隱蔽的內存泄漏——pthread_create 屬性設置不當導致


最近解決了一個隱蔽的內存泄漏問題,我們的進程是HA模式,用戶不停的切換,會導致內存不停的增長,切換一次,再切回來內存便增加8M左右。原因就是是pthread_create後的僵死線程沒有釋放導致的內存持續增長。


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 avoid memory leaks.

也就說線程執行完後如果不join的話,線程的資源會一直得不到釋放而導致內存泄漏!


解決辦法


創建線程前設置 PTHREAD_CREATE_DETACHED 屬性
 pthread_attr_t attr;
 pthread_t thread;
 thread_attr_init (&attr);
 pthread_attr_setdetachstate (&attrPTHREAD_CREATE_DETACHED);
 pthread_create (&thread, &attr&thread_function, NULL);
 pthread_attr_destroy (&attr);

這樣就會在線程return/pthread_exit後釋放內存。

其實用valgrind檢查時會提示pthread_create沒有釋放的問題,這樣的問題也只有在長時間運行時,慢慢積累這一點點的內存纔會暴露出來。



屬性值不能直接設置,須使用相關函數進行操作,初始化的函數爲pthread_attr_init,這個函數必須在pthread_create函數 之前調用。屬性對象主要包括是否綁定、是否分離、堆棧地址、堆棧大小、優先級。默認的屬性爲非綁定、非分離、缺省1M的堆棧、與父進程同樣級別的優先級。

線程的分離狀態決定一個線程以什麼樣的方式來終止自己。在上面的例子中,我們採用了線程的默認屬性,即爲非分離狀態,這種情況下,原有的線程等待 創建的線程結束。只有當pthread_join()函數返回時,創建的線程纔算終止,才能釋放自己佔用的系統資源。而分離線程不是這樣子的,它沒有被其 他的線程所等待,自己運行結束了,線程也就終止了,馬上釋放系統資源。程序員應該根據自己的需要,選擇適當的分離狀態。設置線程分離狀態的函數爲pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)。第二個參數可選爲PTHREAD_CREATE_DETACHED(分離線程)和 PTHREAD _CREATE_JOINABLE(非分離線程)。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章