C+標準庫 std:thread 的簡單使用,一文搞定還不簡單?

2020-12-25 騰訊網

std::thread是 C++ 11 新引入的標準線程庫。在同樣是 C++ 11 新引入的 lambda 函數的輔助下,std::thread用起來特別方便:

int a = 1;

std::thread thread([a](int b) {

return a + b;

}, 2);

它唯一有點令人疑惑的地方在於其提供的join和detach函數,字面上的意思是前者合併線程,後者分離線程。無論是合併還是分離,都會導致std::thread::joinable()返回false,而在此之前為true(即使這個新建線程的任務已經執行完畢!)。

合併線程的含義比較清楚,就是綁定的線程合併到當前線程執行,當前線程被堵塞,直到被合併的線程執行完畢。

分離線程則是新創建的線程和std::thread對象分離,創建的線程獨立運行。std::thread將不再持有該線程。有人可能覺得這種毫無意義,但理論上還是有的,比如分離後,我們就可以析構std::thread對象,而不會影響創建的線程(創建的線程會繼續運行)。

int a = 1;

{

std::thread thread1([a](int b) {

return a + b;

}, 1);

thread1.detach();

}

{

std::thread thread2([a](int b) {

return a + b;

}, 2);

}

以上面代碼為例,thread1不會出錯,但thread2會導致程序退出。原因是std::thread的析構函數裡設置了如果線程既沒有合併也沒有分離,程序就會自動退出!

~thread() {

if (joinable()) std::terminate();

}

其原始碼位於https://gcc.gnu.org/onlinedocs/gcc-7.5.0/libstdc++/api/a00158_source.html,實現非常簡單,是基於pthread的封裝,其內容只有線程 ID :

class thread {

public:

typedef __gthread_t native_handle_type;

class id {

native_handle_type _M_thread;

};

private:

id _M_id;

}

相關焦點

  • 線程安全之std::atomic探索
    試試C++11封裝的原子數據類型(std::atomic)吧。什麼是原子數據類型簡單地說,原子數據類型能保證線程之間不會發生數據競爭(data race),因此能保證線程安全(thread safe)。對於我們用戶來說,就不需要對需要多線程訪問的數據添加互斥鎖。
  • UNIX(多線程):03--- 認識std::thread
    std::thread 在 <thread> 頭文件中聲明,因此使用
  • C++11並發編程:多線程std::thread
    一:概述C++11引入了thread類,大大降低了多線程使用的複雜度,原先使用多線程只能用系統的API,無法解決跨平臺問題,一套代碼平臺移植,對應多線程代碼也必須要修改。現在在C++11中只需使用語言層面的thread可以解決這個問題。
  • 手把手入門硬核c STD
    這套課程是c語言標準庫的講解,主要涉及到的知識點有,時間時區,內存管理,算法,寬字符API,數學庫,字符檢測等,詳細見目錄。你可能會問:老師,為什麼要學習這套課程呢?C語言我會呀。這邊我解答一下。這套教程可不是簡簡單單的講解C語言哦,在這套教程之前我們就出了一套手把手入門硬核c語言 那套雖然基礎但是已經和市面上的教程不一樣了,更加硬核。而手把手入門C std 是在 硬核c的基礎上的進階版本,更更硬核的教程。我們會全面講解C 標準庫,在開發獨立引擎或者渲染器或者原生分布式伺服器的時候,我們會用到大量的c語言 API。
  • Qt使用C/C++擴展Python內置模塊
    之前和大家介紹過在C/C++中嵌入Python,本次和大家分享下使用C/C++擴展Python內置模塊的方法。被擴展出來的新模塊可以做兩件無法直接在Python中完成的事情:一可以實現新的內置對象類型,二則可以調用C庫函數和一些其他的系統調用。
  • c編譯器so easy,gcc c編譯器生成、使用動靜態庫
    >當系統加載可執行代碼時候,能夠知道其所依賴的庫的名字,但是還需要知道絕對路徑。c編譯器作為常用軟體之一,並非具備無法逾越難度。對於c編譯器的學習,往往需要具備一定耐心。本文對c編譯器的講解基於gcc c編譯器,同時本文承接「c編譯器so easy,gcc c編譯器生成、使用動靜態庫(上篇)」一文而談,不了解的朋友可以先回顧一番哦。此外,本文主要內容為gcc生成靜態和動態連結庫的示例,一起來了解下吧。
  • 在數據科學中使用 C 和 C++ | Linux 中國
    這是一組人工構建的數據,當擬合直線時可以提供相同的結果,但是它們的曲線非常不同。數據文件是一個文本文件,其中的制表符用作列分隔符,前幾行作為標題。該任務將僅使用第一組(即前兩列)。它的標準庫很小,功能也不多,因此人們開發了其它庫來提供缺少的功能。我最常在數字運算中使用該語言,主要是因為其性能。我覺得使用起來很繁瑣,因為它需要很多樣板代碼,但是它在各種環境中都得到了很好的支持。C99 標準是最新版本,增加了一些漂亮的功能,並且得到了編譯器的良好支持。我將一路介紹 C 和 C++ 編程的必要背景,以便初學者和高級用戶都可以繼續學習。
  • 最簡單易懂的C++教程 Day2
    二,頭文件與std(標準命名空間)usingnamespacestd;//聲明命名空間std這一切的一切都要從C++頭文件開始講起,上一講我們說到由於早期C++功能還不完善並不支持命名空間,要編譯時需要將C++翻譯成C代碼,再通過C編譯器完成編譯。
  • 詳細介紹下C/C++那些時間函數
    首先介紹下C++標準中的chrono庫chrono是一個關於時間的庫,起源於boost,現在是C++的標準,話說現在的C++標準好多都是源於boost,要進標準的特性似乎都會先在boost試驗一番。首先看一下使用chrono簡單計時的示例代碼:void func() { std::chrono::time_point<std::chrono::high_resolution_clock> begin = high_resolution_clock:
  • 多線程編程(1):從thread開始,邁入多線程的大門
    本文要完成兩個目標:使用std::thread在如下的demo中,在主線程中使用std::thread創建3個子線程,線程入口函數是do_some_word,在主線程運行結束前等待子線程結束。}在demo中,在構造線程對象std::thread{do_some_work, idx}的時候,還是建議使用{}而不是(),以防止編譯器產生錯誤的決議,具體原因可以參考前文【別再徘徊於{}與()之間了,來學習正確用法】。
  • C++ std::function技術淺談
    1. std::function簡介在討論其原理的時候,我們來熟悉一下這個東西是怎麼使用的,C++標準庫詳細說明了這個的基本使用http://www.cplusplus.com/reference/functional/function/.這裡我們大概總結一下。
  • C++標準庫和std命名空間
    早期的 C++ 還不完善,不支持命名空間,沒有自己的編譯器,而是將C++代碼翻譯成C代碼,再通過C編譯器編譯成目標代碼。這個時候的C++仍然在使用C語言庫,此外還開發了一些新的庫,增加了不少頭文件,例如:iostream.h:輸入輸出頭文件。fstream.h:文件操作頭文件。wchar.h:寬字符處理頭文件。
  • 【線上問題定位】Llvm庫ARM環境崩潰問題
    問題原因分析問題一、當前編譯器默認使用小代碼模型,在jit的重定位模塊resolveAArch64Relocation函數case ELF_AARCH64_PREL32分支中會計算代碼段和.eh_frame段的重定位地址之前的差距,相差超過+/- 2G會觸發斷言,需要使用大代碼模型解除該限制。如下圖所示
  • 走進C++11(三十七)原子操作之 std::atomic
    ,可以方便的使用原子變量,使用原子變量就不用互斥變量來保護該變量了。;T>::valuestd::is_move_assignable<T>::valuestd::atomic<bool> 使用初等模板。
  • json for modern c++的使用
    很多高級語言如python等都對json有良好的支持,方便程式設計師的使用。然而C++對json沒有很好的內置支持,因此往往要引用一些第三方庫。而網上很多json的包,形形色色種類繁多,但是要麼功能不夠強大,要麼難以使用。
  • C++機器學習庫介紹 | 文末送書
    目錄為什麼我們要使用機器學習庫?這是很多新來者都會遇到的問題,庫對於機器學習中的重要性是什麼?讓我試著在這一節解釋一下。比如說,經驗豐富的專業人士和行業老手已經付出了艱辛的努力,並想出了解決問題的辦法。你更願意使用它,還是願意花幾個小時從頭開始重新創建相同的東西?後一種方法通常沒有什麼意義,尤其是當你在DDL前的工作或學習。
  • JNI-Thread中start方法調用與run方法回調分析
    我們希望該方法簡單地輸出一個"hello jni",於是定義如下方法,並將其保存在cn_tera_jni_JniTest.c文件中(這裡文件名不需要一致,不過為了可維護性,我們應當定義一致)#include "cn_tera_jni_JniTest.h"JNIEXPORT void JNICALL Java_cn_tera_jni_JniTest_jniHello
  • 聊一聊C++bind函數使用
    程序是這麼寫的, speaker_play_routine_ = new boost::thread(boost::bind(&Speaker::playRoutine, this)); 這是我們一個語音播放的一行代碼。
  • 實現32位簡單版Windows和Linux雙平臺的C++運行庫
    」運行庫實現「章節學到的知識,現編寫」運行庫實現「一文。我們計劃讓Mini CRT能夠同時支持Windows和 Linux兩個作業系統Mini CRT的實現應該儘量簡單,以展示CRT的實現為目的,並不追求功能和性能,基本上是「點到為止」為了使CRT能夠同時支持Linux和 Windows兩個平臺,必須針對這兩個作業系統環境的不同進行條件編譯。在Mini CRT中,我們使用宏WIN32為標準來決定是Windows還是Linux。