C ++线程:连接完全做什么?

时间:2016-03-30 08:23:59

标签: c++ multithreading join

以下代码来自Dash的{​​{1}}示例。

std::thread
  

join阻塞当前线程,直到* this标识的线程完成执行。

线程是否在调用#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(); 到底做了什么?

4 个答案:

答案 0 :(得分:6)

两个线程同时启动并执行相同的长度。因此,在你的情况下join没有做太多 - 两个线程同时开始并在同一时间结束。

  1. 线程1启动,开始睡眠1秒
  2. 线程2开始,开始睡眠1秒
  3. 加入1被叫 - 程序将等待1秒钟,以便线程1完成
  4. 这意味着线程2也完成了
  5. 加入2被叫,这简直就是线程2已经完成
  6. 正如您所看到的,在步骤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";
    }
    

    您将观察到如果线程foo持续1秒并且线程条持续2秒,那么“Joined Foo”和“Joined Bar”输出之间会有1秒的延迟。如果你把foo的持续时间反转为2秒,bar反转1秒,那么2秒后会打印“Joined Foo”输出,之后会立即打印“Joined Bar”。

答案 1 :(得分:2)

在一句话中,木匠等待受害者完成其执行。

答案 2 :(得分:1)

加入阻塞当前线程,意味着它将不会继续运行,直到调用连接的线程完成。辅助线程开始在构造函数调用上运行。 例如。主线程将停止执行,直到线程a完成其运行,然后主线程将恢复

答案 3 :(得分:0)

我举一个例子来说明join做什么和可以用来做什么。假设我有一大堆计算B要做,我希望使用多个线程并行执行它们,以利用我拥有的多个CPU内核。

让我们从main开始调用线程。我们说我有四个核心,所以我将使用四个线程。从帖子main我创建了四个新的&#39; worker&#39;线程,并为它们提供所有B的子集来处理。

我现在有5个正在运行的线程。但是在我的main线程中,我想使用计算结果,所以我必须等待其他线程完成。这是通过join完成的,通过在四个线程上逐个调用join,我确保它们都完成了计算,因此我可以安全地阅读并使用结果。

通过在四个工作线程中的一个上从join调用main,我让main等待该工作线程。因此,main会在等待时停止,这是一个“阻止通话”。