[英]Waiting for a thread to finish and future
Having such simple code:有这么简单的代码:
void func(std::promise<int>* p) {
int a = 10, b = 5;
int result = a + b;
std::cout << "From inside the Thread...." << std::endl;
p->set_value(result);
}
int FP_main() {
std::promise<int> p;
std::future<int> f = p.get_future();
std::thread th(func, &p);
int ret = f.get();
std::cout << "returned val: " << ret << std::endl;
th.join();
return 0;
}
Why do we need the join
function call if there is get
call just 2 lines above?如果上面只有 2 行有get
调用,为什么我们需要join
函数调用? Isn't the get
function waiting for a thread to finish? get
函数不是在等待线程完成吗?
Because the thread is not the promise.因为线程不是承诺。
Promise is finished, but thread is not. Promise 已完成,但线程未完成。
p->set_value(result);
// ...
// HERE
// ...
}
That are the last lines of func
.那是func
的最后func
行。 The thread will now do its cleanups, will call destructors, etc. All while the promise is finished.线程现在将进行清理,调用析构函数等。所有的时间都是在 promise 完成的时候。 Of couse, in 'HERE' the thread may a ton of other work - you can write a 1-hour long task in HERE to keep the thread alive and it will have nothing to do with the promise.当然,在“HERE”中,线程可能会进行大量其他工作——您可以在 HERE 中编写一个长达 1 小时的任务以保持线程处于活动状态,并且它与承诺无关。
That's probably all clear already.这可能已经很清楚了。
The last interesting bit is here:最后一个有趣的地方在这里:
int FP_main() {
//...
std::thread th(func, &p);
//...
th.join();
return 0;
}
The 'th' is a local variable. 'th' 是一个局部变量。 When the main() returns, the destructor of th
will be invoked.当 main() 返回时,将调用th
的析构函数。 And that destructor throws an exception when the thread in question is not finished and not join'ed.当有问题的线程未完成且未连接时,该析构函数会引发异常。
If the thread were busy after setting the value of the promise (ie doing destructors, or doing some 1-hour-long job), the std::thread's destructor invoked by } after return 0;如果在设置promise 值后线程很忙(即执行析构函数,或执行一些1 小时长的工作),则在返回0 之后由} 调用的std::thread 的析构函数; would throw and crash the program.会抛出并崩溃程序。 Hence, you need to join.因此,您需要加入。
Why do we need the
join
function call if there isget
call just 2 lines above?如果上面只有 2 行有get
调用,为什么我们需要join
函数调用?
Destroying a joinable std::thread
object results in std::terminate()
being called.销毁可连接的std::thread
对象会导致调用std::terminate()
。 This is regardless of whether or not its associated thread is done.这与它的关联线程是否完成无关。 So, the call to get()
on the future is irrelevant when it comes to having to call join()
on a joinable std::thread
object before it is destroyed.因此,当需要在可连接的std::thread
对象上调用join()
在它被销毁之前调用get()
是无关紧要的。
If you don't want to have to call join()
, then you could just call detach()
on the std::thread
somewhere before its destruction.如果您不想调用join()
,那么您可以在std::thread
销毁之前的某个地方调用detach()
。 This way, the thread won't be joinable at the moment of destruction.这样,线程在销毁时将无法加入。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.