C++11線程常識

定義一個線程

#include <thread>
#include <chrono>
#include <iostream>

void doSomething()
{
  while(true)
  {
     std::cout << "hello world" << std::endl;
     std::this_thread::sleep_for(std::chrono::seconds(1));
  }
}

int main()
{
  std::thread t(doSomething);  //① 
  if(t1.joinable())
  {
    t1.join();                 //②
  }
}

以上代碼簡單的頂一個線程,主線程阻塞等待子線程退出糙捺,子線程每個一秒打印一個"hello world". 代碼中① 聲明定義了一個線程弧关,我們往thread對象t中傳入一個函數(shù)指針,此后線程開始運行,該回調(diào)函數(shù)被調(diào)用碧注。代碼②調(diào)用了std::thtrad::join()函數(shù),該函數(shù)表示子線程與主線程的關(guān)系糖赔,主線程在此處將會等待子線程結(jié)束,并回收子線程的資源(一般一個子線程將會占用32M左右的內(nèi)存放典,如果無線開啟線程而不加以回收壳影,那么系統(tǒng)將會資源耗盡),需要注意的是掺栅,我們在調(diào)用std::thtrad::join()函數(shù)之前需要檢查這個線程是否是可以join的,否則會出現(xiàn)core_dump沙绝。
除了std::thtrad::join(),std::thread還提供了std::thtrad::detach()函數(shù)强饮,該函數(shù)表示主線程和子線程的關(guān)系是分離的行您,當(dāng)子線程結(jié)束時,其占用的內(nèi)存將自動釋放笛质。
另一個值得注意的是,如果在thread對象被銷毀時還沒有決定好線程銷毀的方式(join/detach), 那么在thread對象被銷毀時,析構(gòu)函數(shù)將會調(diào)用std::terminate()終止程序。

傳遞參數(shù)

上一節(jié)中我們的線程接收的函數(shù)指針沒有參數(shù)列表,那么如果有參數(shù)与学,或者參數(shù)還有const &, &&等限定符抑片,該怎么辦呢,參考以下代碼:

void doSomething(const int& num, std::string&& str)
{
  while(true)
  {
     std::cout << str << std::endl;
     std::this_thread::sleep_for(std::chrono::seconds(num));
  }
}

int main()
{
  int num = 1;
  std::string str("hello world");
  std::thread t1(doSomething, std::ref(num), std::move(str));  //① 
  if(t1.joinable())
  {
    t1.join();                 //②
  }
}
  1. 如果參數(shù)類型是一個拷貝焰枢,那直接傳遞蚓峦,沒有任何花里胡哨
  2. 如果參數(shù)類型是引用,那么可參考std::bind的語法济锄,需要使用std::ref將其聲明為一個引用
  3. 如果是右值應(yīng)用暑椰,那么需要使用std::move將其聲明為一個右值引用

移交線程歸屬權(quán)

STL庫中有許多對象是資源獨占型的,比如一個眾所周知的例子就是std::unique_ptr, 其實現(xiàn)原理其實就是荐绝,拷貝構(gòu)造函數(shù)和復(fù)制重載運算符被delete掉了一汽,例如:

unique_ptr(const unique_ptr&) = delete;
uuique_ptr& operator=(const unique_ptr&) = delete;

雖然std::thread是無法復(fù)制的,但是他是可以移動的(其實現(xiàn)依賴右值引用)低滩。因此我們可以寫下如下代碼:

int main() 
{
  std::thread t1([](){
    while(1)
    {
      std::this_thread::sleep_for(std::chrono::seconds(1));
      std::cout << "hello" << std::endl;
    }
  });

  std::thread t2([](){
    while(1)
    {
      std::this_thread::sleep_for(std::chrono::seconds(1));
      std::cout << "world" << std::endl;
    }
  });

  //t1.detach();
  t1 = std::move(t2); //③
  
  if(t1.joinable())
  {
    t1.join();
  }
  if(t2.joinable())
  {
    t2.join();
  }


  return 0;
}

以上代碼將會在③處出現(xiàn)錯誤召夹,std::terminate()將會被調(diào)用岩喷,因為t1重新接收了t2,而t1原來的實例將被釋放监憎,但卻沒指定其方式是join還是detach均驶。因此我們需要將③行之前的注釋解開。

相關(guān)函數(shù)

最大線程數(shù)

中所周知啊枫虏,如果在單核cpu上妇穴,所有的程序都是順序執(zhí)行的,但我們依然可以進行多線程操作隶债,這是因為系統(tǒng)在執(zhí)行過程中頻繁的從多個線程之間切換任務(wù)腾它,于是給用戶以程序并行的體驗,但是這個操作勢必會帶來更多的資源消耗死讹。標準庫中提供一個函數(shù)std::thread::hardware_concurrency()瞒滴,該函數(shù)返回系統(tǒng)最大支持線程數(shù)的一個指標,之所以叫他指標是因為如果資源數(shù)無法獲取赞警,那么函數(shù)將返回0妓忍。因此我們要注意盡信書不如無書。

線程表示符

可使用std::this_thread::get_id()得到當(dāng)前線程的id愧旦。

阻塞線程

可使用std::this_thread_sleep_for(std::chrono::second(1));使線程阻塞1s世剖,該操作會將線程掛起,因此不會對CUP造成過多負載笤虫。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末旁瘫,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子琼蚯,更是在濱河造成了極大的恐慌酬凳,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件遭庶,死亡現(xiàn)場離奇詭異宁仔,居然都是意外死亡,警方通過查閱死者的電腦和手機峦睡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門翎苫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人赐俗,你說我怎么就攤上這事拉队。” “怎么了阻逮?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長秩彤。 經(jīng)常有香客問我叔扼,道長事哭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任瓜富,我火速辦了婚禮鳍咱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘与柑。我一直安慰自己谤辜,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布价捧。 她就那樣靜靜地躺著丑念,像睡著了一般。 火紅的嫁衣襯著肌膚如雪结蟋。 梳的紋絲不亂的頭發(fā)上脯倚,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音嵌屎,去河邊找鬼推正。 笑死,一個胖子當(dāng)著我的面吹牛宝惰,可吹牛的內(nèi)容都是我干的植榕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼尼夺,長吁一口氣:“原來是場噩夢啊……” “哼内贮!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起汞斧,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤夜郁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后粘勒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體竞端,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年庙睡,在試婚紗的時候發(fā)現(xiàn)自己被綠了事富。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡乘陪,死狀恐怖统台,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情啡邑,我是刑警寧澤贱勃,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響贵扰,放射性物質(zhì)發(fā)生泄漏仇穗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一戚绕、第九天 我趴在偏房一處隱蔽的房頂上張望纹坐。 院中可真熱鬧,春花似錦舞丛、人聲如沸耘子。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谷誓。三九已至,卻和暖如春欧聘,著一層夾襖步出監(jiān)牢的瞬間片林,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工怀骤, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留费封,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓蒋伦,卻偏偏與公主長得像弓摘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子痕届,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容