c++11中thread join和detach的區別

線程狀態:windows

在一個線程的生存期內,能夠在多種狀態之間轉換,不一樣的操做系統能夠實現不一樣的線程模型,定義許多不一樣的線程狀態,每一個狀態還能夠包含多個子狀態,但大致來講,以下幾種狀態是通用的:api

1)就緒:參與調度,等待被執行,一旦被調度選中,當即開始執行併發

2)運行:佔用CPU,正在運行中函數

3)休眠:暫不參與調度,等待特定事件發生spa

4)停止:已經運行完畢,等待回收線程資源操作系統

線程環境:線程

線程存在於進程之中,進程內全部全局資源對於內部每一個線程都是可見的。指針

進程內典型全局資源以下:對象

1)代碼區:這意味着當前進程空間內全部的可見的函數代碼,對於每一個線程來講,也是可見的進程

2)靜態存儲區:全局變量,靜態空間

3)動態存儲區:堆空間

線程內典型的局部資源:

1)本地棧空間:存放本線程的函數調用棧,函數內部的局部變量等

2)部分寄存器變量:線程下一步要執行代碼的指針偏移量

一個進程發起後,會首先生成一個缺省的線程,一般稱這個線程爲主線程,C/C++程序中,主線程就是經過main函數進入的線程,由主線程衍生的線程成爲從線程,從線程也能夠有本身的入口函數,至關於主線程的main函數,這個函數由用戶指定。經過thread構造函數中傳入函數指針實現,在指定線程入口函數時,也能夠指定入口函數的參數。就像main函數有固定的格式要求同樣,線程的入口函數也能夠有固定的格式要求,參數一般都是void類型,返回類型根據協議的不一樣也不一樣,pthread中是void,winapi中是unsigned int,並且都是全局函數。

最多見的線程模型中,除主線程較爲特殊以外,其餘線程一旦被建立,相互之間就是對等關係,不存在隱含的層次關係。每一個進程可建立的最大線程數由具體實現決定。

不管在windows中仍是Posix中,主線程和子線程的默認關係是:不管子線程執行完畢與否,一旦主線程執行完畢退出,全部子線程執行都會終止。這時整個進程結束或僵死,部分線程保持一種終止執行但還未銷燬的狀態,而進程必須在其全部線程銷燬後銷燬,這時進程處於僵死狀態。線程函數執行完畢退出,或以其餘很是方式終止,線程進入終止態,可是爲線程分配的系統資源不必定釋放,可能在系統重啓以前,一直都不能釋放,終止態的線程,仍舊做爲一個線程實體存在於操做系統中,何時銷燬,取決於線程屬性。在這種狀況下,主線程和子線程一般定義如下兩種關係:

一、可會合(joinable):這種關係下,主線程須要明確執行等待操做,在子線程結束後,主線程的等待操做執行完畢,子線程和主線程會合,這時主線程繼續執行等待操做以後的下一步操做。主線程必須會合可會合的子線程。在主線程的線程函數內部調用子線程對象的wait函數實現,即便子線程可以在主線程以前執行完畢,進入終止態,也必須執行會合操做,不然,系統永遠不會主動銷燬線程,分配給該線程的系統資源也永遠不會釋放。

二、相分離(detached):表示子線程無需和主線程會合,也就是相分離的,這種狀況下,子線程一旦進入終止狀態,這種方式經常使用在線程數較多的狀況下,有時讓主線程逐個等待子線程結束,或者讓主線程安排每一個子線程結束的等待順序,是很困難或不可能的,因此在併發子線程較多的狀況下,這種方式也會常用。

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

線程的分離狀態決定一個線程以什麼樣的方式來終止本身,在默認的狀況下,線程是非分離狀態的,這種狀況下,原有的線程等待建立的線程結束,只有當pthread_join函數返回時,建立的線程纔算終止,釋放本身佔用的系統資源,而分離線程沒有被其餘的線程所等待,本身運行結束了,線程也就終止了,立刻釋放系統資源。

相關文章
相關標籤/搜索