pthread_join與pthread_detach細節問題


http://www.360doc.com/content/13/0106/09/9171956_258497083.shtml

 

pthread_t    pthr;

pthread_create(&pthr, NULL, thread_handler, NULL);

...

void* thread_handler(void* arg)

{

    /* do something */

    pthread_join(pthr, NULL);

}

 

上面的代碼不好使,pthread_join不能放在pthread調用的handler內,雖然不報錯,但是thread無法正常回收,如果多次創建thread,內存會越來越大(另一種形式的內存泄露)。

正確的做法是在handler外面pthread_join:

 

pthread_t    pthr;

pthread_create(&pthr, NULL, thread_handler, NULL);

pthread_join(pthr, NULL);

...

void* thread_handler(void* arg)

{

    /* do something */

}

 

如果不用pthread_join,改用pthread_detach呢?那最方便,但要注意:pthread_detach最好是放在handler里面第一句。

 

void* thread_handler(void* arg)

{

    pthread_detach(pthr);

    /* do something */

}

 

如果pthread_create后緊跟pthread_detach,有可能會出錯。

 

 

pthread_detach(pthread_self())
linux線程執行和windows不同,pthread有兩種狀態joinable狀態和unjoinable狀態,
如果線程是joinable狀態,當線程函數自己返回退出時或pthread_exit時都不會釋放線程所占用堆棧和線程描述符(總計8K多)。只有當你調用了pthread_join之后這些資源才會被釋放。
若是unjoinable狀態的線程,這些資源在線程函數退出時或pthread_exit時自動會被釋放。
unjoinable屬性可以在pthread_create時指定,或在線程創建后在線程中pthread_detach自己, 如:pthread_detach(pthread_self()),將狀態改為unjoinable狀態,確保資源的釋放。或者將線程置為 joinable,然后適時調用pthread_join.
其實簡單的說就是在線程函數頭加上 pthread_detach(pthread_self())的話,線程狀態改變,在函數尾部直接 pthread_exit線程就會自動退出。省去了給線程擦屁股的麻煩
 
 
pthread_self 
頭文件
 #include <pthread.h> 
函數原型
 pthread_t pthread_self(void);
 函數作用:獲得線程自身的ID。pthread_t的類型為unsigned long int,所以在打印的時候要使用%lu方式,否則將產生奇怪的結果。
功能
 獲取當前調用線程的 thread identifier(標識號).
 
 
近來發現 在線程函數第一行調用 pthread_detach(pthread_self()) 返回值是22不是0,后來在網上找到以下話語:
linux線程執行和windows不同,pthread有兩種狀態joinable狀態和unjoinable狀態,如果線程是joinable狀態,當線程函數自己返回退出時或pthread_exit時都不會釋放線程所占用堆棧和線程描述符(總計8K多)。只有當你調用了pthread_join之后這些資源才會被釋放。 
 若是unjoinable狀態的線程,這些資源在線程函數退出時或pthread_exit時自動會被釋放。
unjoinable屬性可以在pthread_create時指定,或在線程創建后在線程中pthread_detach自己,如:pthread_detach(pthread_self()),將狀態改為unjoinable狀態,確保資源的釋放。或者將線程置為joinable,然后適時調用pthread_join.
在程序運行中檢查/proc/ <pid> /maps文件,若看到大概8K左右的很多虛擬內存碎片,基本上可以確認是線程資源泄漏造成的300個線程后pthread_create失敗。
 不知是否因為自己,先對要創建的線程做了以下屬性設定,
 pthread_attr_init(&attr);
 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 然后又在線程函數中使用
 pthread_detach(pthread_self());
 兩段代碼作用有沖突。
===============================================================================
pthread_detach(threadid)和pthread_detach(pthread_self())的區別應該是調用他們的線程不同,沒其他區別。
pthread_detach(threadid)函數的功能是使線程ID為threadid的線程處於分離狀態,一旦線程處於分離狀態,該線程終止時底層資源立即被回收;否則終止子線程的狀態會一直保存(占用系統資源)直到主線程調用pthread_join(threadid,NULL)獲取線程的退出狀態。
 通常是主線程使用pthread_create()創建子線程以后,一般可以調用pthread_detach(threadid)分離剛剛創建的子線程,這里的threadid是指子線程的threadid;如此以來,該子線程止時底層資源立即被回收;
 被創建的子線程也可以自己分離自己,子線程調用pthread_detach(pthread_self())就是分離自己,因為pthread_self()這個函數返回的就是自己本身的線程ID。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM