2016-03-30 37 views
3

以下代碼來自Dash的示例,用於std::threadC++線程:什麼連接完成?

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

void foo() 
{ 
    // simulate expensive operation 
    std::this_thread::sleep_for(std::chrono::seconds(1)); 
} 

void bar() 
{ 
    // simulate expensive operation 
    std::this_thread::sleep_for(std::chrono::seconds(1)); 
} 

int main() 
{ 
    std::cout << "starting first helper...\n"; 
    std::thread helper1(foo); 

    std::cout << "starting second helper...\n"; 
    std::thread helper2(bar); 

    std::cout << "waiting for helpers to finish..." << std::endl; 
    helper1.join(); 
    // std::cout << "after join... \n"; 
    helper2.join(); 

    std::cout << "done!\n"; 
} 

加入阻塞當前線程,直到被*此完成它的執行所標識的線程。

join調用後線程執行嗎?

如果我之後添加std::cout << "after join... \n"第一個加入,after join...done!將輸出連續,無延遲,這就像被後第二join放。

具體來說,整個效果是:先後連續打印前三行,然後休眠一段時間,最後連續打印最後兩行,沒有延遲。

a.join(); 
b.join(); 
cout << "something..."; 
// or 
a.join(); 
cout << "something..."; 
b.join(); 

讓我困惑的是:爲什麼兩種方式有相同的效果? join究竟做了什麼?

+1

http://www.cplusplus.com/reference/thread/thread/join/ –

回答

5

你的兩個線程同時啓動並執行相同的長度。因此,在你的情況下,join做的並不多 - 兩個線程同時開始並同時結束。

  1. 線程1周開始,開始睡覺1秒
  2. 線程2周開始,開始睡覺1秒
  3. 加入1個叫 - 程序將等待1秒通過線程1完成
  4. 這意味着線程2結束以及
  5. 加入2叫,這簡直是直通的線程2已經結束

正如你可以發在步驟5之前或之後打印任何內容都不會改變任何內容

一個更好的例子是這樣的:

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

using namespace std; 

void foo() 
{ 
    // simulate expensive operation 
    cout << "Foo Start" << endl; 
    this_thread::sleep_for(chrono::seconds(1)); 
    cout << "Foo Stop" << endl; 
} 

void bar() 
{ 
    // simulate expensive operation 
    cout << "Bar Start" << endl; 
    this_thread::sleep_for(chrono::seconds(2)); 
    cout << "Bar Stop" << endl; 
} 

int main() 
{ 
    thread helper1(foo); 
    thread helper2(bar); 

    helper1.join(); 
    cout << "Joined Foo... \n"; 
    helper2.join(); 
    cout << "Joined Bar... \n"; 
} 

你會發現,如果線程富持續1秒,螺紋杆2秒鐘,然後將「加盟富」和「加入吧」輸出會來中間有1秒的延遲。如果將持續時間反轉爲foo爲2秒,而反轉爲1秒,則「連接的Foo」輸出將在2秒後打印,之後立即打印「連接條」。

1

加入塊當前線程,這意味着它不會繼續運行,直到連接被調用的線程完成。輔助線程開始在構造函數調用上運行。 例如主線程將停止執行,直到線程完成其運行,然後主線程將恢復

0

在一句話中,連接器將等待被約束者完成其執行。

0

我舉一個例子來說明join的用途。假設我有大量計算B的計算,並且我想使用多線程並行執行它們以利用我擁有的多個CPU核心。

讓我們來調用線程我將從main開始。假設我有四個內核,所以我將使用四個線程。從線程main我創建了四個新的「工作」線程,並給它們全部處理B的子集。

我現在有5個正在運行的線程。但在我的main線程中,我想使用計算結果,所以我必須等待其他線程完成。這通過join完成,通過在四個線程上逐一調用join,我確保它們都完成計算,因此我可以安全地閱讀和使用結果。

通過在四個工作線程中的一個上調用join來自main,我正在使main等待該工作線程。所以main會在等待時暫停,這是一個'阻止呼叫'。

相關問題