C++11中thread庫join和detach的區別
線程狀態
在一個線程的生存期中,可以在多種狀態之間轉換,不同的操作系統可以實現不同的線程模型,定義許多的線程狀態,且每個狀態還可以包含多個子狀態。但大體來說,所有的操作系統有幾種狀態是通用的。
- 就緒態:參與調度,等待被執行,一旦被CPU選中,就立即開始執行。
- 運行態:占用CPU,正在被運行。
- 休眠態:暫不參與調度,等待特定的事件發生后轉化為就緒態。
- 中止態:已經運行完畢,等待回收線程資源。
線程環境
線程存在于進程之中,進程內所有的全局資源對于內部每個線程都是可見的。
進程內典型的全局資源(線程可見資源)如下:
- 代碼區:意味著當前進程空間內所有的函數代碼均可見,對于每個線程來說,都是可見的。
- 靜態存儲區:全局變量、可訪問的靜態變量。
- 動態存儲區:動態生成的變量(new)。
線程內典型的局部資源如下:
1.本地棧空間:存放本線程的函數調用棧,函數內部的局部變量等。
2.部分寄存器變量:線程下一步要執行代碼的指針偏移量。
join和detach的區別
一個進程發起后,會首先生成一個缺省的線程,通常稱這個線程為主線程,C/C++程序中,主線程就是通過main函數進入的線程,由主線程衍生的線程成為從線程(也稱之為子線程),從線程也可以有自己的入口函數,相當于主線程的main函數,這個函數由用戶指定。通常使用thread創建子線程。通過thread構造函數中傳入函數指針實現,在指定線程入口函數時,也可以指定入口函數的參數。
最常見的線程模型中,除主線程較為特殊之外,其他線程一旦被創建,相互之間就是對等關系,不存在隱含的層次關系。每個進程可創建的最大線程數由具體實現決定。
無論在windows中還是Posix中,主線程和子線程的默認關系都是:無論子線程執行完畢與否,一旦主線程執行完畢退出,所有子線程執行都會終止。部分線程保持一種終止執行但還未銷毀的狀態,而進程必須在其所有線程銷毀后銷毀,這時整個進程處于僵死狀態(可能造成程序崩潰)。
在這種情況下,主線程和子線程通常定義以下兩種關系:
1、可會合(joinable):這種關系下,主線程需要明確執行等待操作,在子線程結束后,主線程的等待操作執行完畢,子線程和主線程會合,這時主線程繼續執行等待操作之后的下一步操作。主線程必須會合可會合的子線程。在主線程的線程函數內部調用子線程對象的wait函數,即使子線程能夠在主線程之前執行完畢,進入終止態,也必須執行會合操作,否則,系統永遠不會主動銷毀線程,分配給該線程的系統資源也永遠不會釋放。
2、相分離(detached):這種關系下,子線程無需和主線程會合,也就是相分離的,這種情況下,子線程一旦進入終止狀態,這種方式常用在線程數較多的情況下。有時讓主線程逐個等待子線程結束或者讓主線程安排每個子線程結束的等待順序,是很困難或不可能的,所以在并發子線程較多的情況下,這種方式也會經常使用。
總結
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!
原文鏈接:https://blog.csdn.net/qq135595696/article/details/121387692