c++11_多線程_1:多線程機理

c++11線程介紹

  • 在c++11標準線程庫之前的相關線程庫:要麼是屬於某個單獨平臺的,例如:POSIX線程庫pthread(Linux),Windows線程庫(Windows winapi);要麼需要第三方庫支持,如第三方數據庫:Boost線程庫。
  • 線程與進程顯著區別:不同線程間可共享同一地址資源(內存、全局變量);不同的進程間擁有獨立的地址空間,相互間不共享。
  • 線程的幾個狀態
    • 在一個線程的生存期內,可以在多種狀態之間轉換,不同的操作系統可以實現不同的線程模型,定義許多不同的線程狀態,每個狀態還可以包含多個子狀態,但大體來說,如下幾種狀態是通用的:
      • 就緒:參與調度,等待被執行,一旦被調度選中,立即開始執行
      • 運行:佔用CPU,正在運行中
      • 休眠:暫不參與調度,等待特定事件發生
      • 中止:已經運行完畢,等待回收線程資源(此時佔用資源並沒有釋放)
  • c++11線程的產生:
    • 一個進程發起後,會首先生成一個缺省的線程,通常稱這個線程爲主線程,C/C++程序中,主線程就是通過main函數進入的線程,由主線程衍生的線程成爲從線程,從線程也可以有自己的入口函數,相當於主線程的main函數,這個函數由用戶指定。通過thread類的構造函數中傳入函數實現,在指定線程入口函數時,也可以指定入口函數的參數。
  • 主線程與子線程的關係(join與detach的實例在下一篇中記錄):
    • 無論子線程執行完畢與否,一旦主線程執行完畢退出,所有子線程執行都會終止。這時整個進程結束或僵死,部分線程保持一種終止執行但還未銷燬的狀態,而進程必須在其所有線程銷燬後銷燬,這時進程處於僵死狀態,爲了防止這種現象出現必須使用join或detach。
    • 線程函數執行完畢退出,或以其他非常方式終止,線程進入終止態,但是爲線程分配的系統資源不一定釋放,可能在系統重啓之前,一直都不能釋放,終止態的線程,仍舊作爲一個線程實體存在於操作系統中,什麼時候銷燬,取決於線程屬性。而線程屬性是由join()和detach()決定的:
      • join函數(匯合線程):當使用join()函數時,主調線程阻塞,等待被調線程終止,然後主調線程回收被調線程資源,並繼續運行
      • detach函數(分離線程):當使用detach()函數時,主調線程繼續運行,被調線程駐留後臺運行,主調線程無法再取得該被調線程的控制權。當主調線程結束時,由運行時庫負責清理與被調線程相關的資源。
      • join與detach都是保證線程正常退出並回收所佔資源,區別在於兩者是否阻塞主調線程。
      • 注意:
        • 不能在程序中既不使用join()合併線程也不使用detach()分離線程,否則線程所佔資源無法正常釋放
        • 在調用join()或detach()前,需要檢查線程是否是join-able的。
          • 如當join()函數在線程對象上執行,當join()返回時,std::thread 對象與他沒有關聯線程,如果在這樣的對象上再次調用join()函數,那麼它將導致程序終止。
            類似的,調用detach()使std::thread對象沒有鏈接任何線程函數,在這種情況下,在一個std::thread對象上調用detach()函數兩次將導致程序終止。簡單地講就是不要重複join和detach。
          • 爲了確保join和detach函數是作用在join-able線程上的,在調用以上函數時對線程對象進行joinable()判斷,如:

std::thread threadObj(WorkerThread())
if(threadObj.joinable()){
	std::cout<<"Detaching Thread"<<std::endl;
	threadObj.detach();
}
if(threadObj.joinable()){
	std::cout<<"Detaching Thread"<<std::endl;
	threadObj.detach();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章