以下代码来自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();
到底做了什么?
答案 0 :(得分:6)
两个线程同时启动并执行相同的长度。因此,在你的情况下join
没有做太多 - 两个线程同时开始并在同一时间结束。
正如您所看到的,在步骤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
会在等待时停止,这是一个“阻止通话”。