關於多線程join和detach方法的理解

 

        join的作用是保證調用join的線程執行完成後,再執行其它線程。join可以有timeout參數,表示阻塞其它線程timeout秒後,不再阻塞。當前線程運行到這個方法時,會被掛起。而只有調用join方法的線程運行完畢,當前線程才繼續運行。

        可以將兩個交替執行的線程合併爲順序執行的線程。比如在線程B中調用了線程A的Join()方法,直到線程A執行完畢後,纔會繼續執行線程B。
         detach是將線程從當前線程分離出去,即不受阻塞,操作系統會將其獨立對待

 

          在任何一個時間點上,線程是可結合的(joinable),或者是分離的(detached)。一個可結合的線程能夠被其他線程收回其資源和殺死;在被其他線程回收之前,它的存儲器資源(如棧)是不釋放的。相反,一個分離的線程是不能被其他線程回收或殺死的,它的存儲器資源在它終止時由系統自動釋放。

        線程的狀態決定一個線程以什麼樣的方式來終止自己。在默認情況下線程是非分離狀態的,這種情況下,原有的線程等待創建的線程結束。只有當join()函數返回時,創建的線程纔算終止,才能釋放自己佔用的系統資源。而分離線程不是這樣子的,它沒有被其他的線程所等待,自己運行結束了,線程也就終止了,馬上釋放系統資源。程序員應該根據自己的需要,選擇適當的分離狀態。所以如果我們在創建線程時就知道不需要了解線程的終止狀態,則可以讓線程以分離狀態啓動。

       要注意的一點是,如果設置一個線程爲分離線程,而這個線程運行又非常快,它很可能在thread_create函數返回之前就終止了,它終止以後就可能將線程號和系統資源移交給其他的線程使用,這樣調用thread_create的線程就得到了錯誤的線程號。要避免這種情況可以採取一定的同步措施,最簡單的方法之一是可以在被創建的線程裏調用thread_cond_timewait函數,讓這個線程等待一會兒,留出足夠的時間讓函數thread_create返回。設置一段等待時間,是在多線程編程裏常用的方法。但是注意不要使用諸如wait()之類的函數,它們是使整個進程睡眠,並不能解決線程同步的問題。

 

        如果線程處於joinable狀態,則只能只能被創建它的線程等待終止

        在Linux平臺默認情況下,雖然各個線程之間是相互獨立的,一個線程的終止不會去通知或影響其他的線程。但是已經終止的線程的資源並不會隨着線程的終止而得到釋放,我們需要調用join() 來獲得另一個線程的終止狀態並且釋放該線程所佔的資源。(說明:線程處於joinable狀態下)

        調用該函數的線程將掛起,等待 th 所表示的線程的結束。 thread_return 是指向線程 th 返回值的指針。需要注意的是 th 所表示的線程必須是 joinable 的,即處於非 detached(遊離)狀態;並且只可以有唯一的一個線程對 th 調用join() 。如果 th 處於 detached 狀態,那麼對 th 的 join() 調用將返回錯誤。

         如果不關心一個線程的結束狀態,那麼也可以將一個線程設置爲 detached 狀態,從而讓操作系統在該線程結束時來回收它所佔的資源。將一個線程設置爲detached 狀態可以通過兩種方式來實現。一種是調用 detach() 函數,可以將線程 th 設置爲 detached 狀態。另一種方法是在創建線程時就將它設置爲 detached 狀態,首先初始化一個線程屬性變量,然後將其設置爲 detached 狀態,最後將它作爲參數傳入線程創建函數,這樣所創建出來的線程就直接處於 detached 狀態。

       總之爲了避免線程的資源在線程結束時不能得到正確釋放,從而避免產生潛在的內存泄漏問題,在線程結束時,要確保該線程處於 detached 狀態,否着就需要調用 join() 函數來對其進行資源回收。


參考:https://blog.csdn.net/xiongping_/article/details/50969155 
 


 

 

 

 

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