[英]Is std::future::get() or std::future::wait() a replacement for std::thread::join()?
在调用future.get()
/ future.wait()
thread.join()
一样返回吗? 我可以只使用它的未来而不直接访问该线程来加入一个线程吗?
std::future::get()
或std::future::wait()
是std::thread::join()
) 的替代品吗?
不,这些是不同的东西。
std::future
是一个同步工具。 它是一个围绕一个值的包装器,该值不能立即可用,但将要可用。 它用于从异步操作(可以在另一个线程中运行)传递数据。 在引擎盖下,它包含一个信号量,如果需要, get()
会在该信号量上等待。
另一方面,一个std::thread
代表一个实际的执行线程。 它可以产生多个结果,从而在其生命周期内提供多个std::promise
。 它应该这样做,因为启动和加入线程是一个相对重量级的操作,比等待未来要重得多。 这就是为什么人们应该更喜欢重用线程,将异步操作发布到线程池并等待它们的结果( std::packaged_task
是一个有用的抽象)。
线程不会在std::future::get()
之后立即退出,即使设置 promise 是它所做的最后一件事。 这些是不相关的事件。
如评论中所述, std::future
与std::thread
没有任何关系。 因此,只有在使用std::thread
时才使用std::thread::join
,如果使用std::future
::future 则使用std::future::get
/ std::future::wait
。
在std::future
引擎盖下,有一个线程池接受作业并以智能方式分发它。
使用future
时,您不能 100% 确定是否创建了实际的新线程。 例如,当您使用std::launch::deferred
执行策略创建future
时,执行非常连续。
引用标准:
std::launch::deferred
:任务在第一次请求其结果时在调用线程上执行(延迟评估)
实际上,当您使用std::launch::async
执行策略创建future
时,大多数时候都会启动一个新线程。 用gcc 10
检查生成的代码我可以清楚地看到thread::join
被调用:
std::__future_base::_Async_state_commonV2::_M_complete_async():
pushq %rbp
movq %rsp, %rbp
//more assembly maddness
call std::__future_base::_Async_state_commonV2::_M_join()
这又会导致thread::join()
调用。
std::__future_base::_Async_state_commonV2::_M_join():
pushq %rbp
movq %rsp, %rbp
subq $48, %rsp
movq %rdi, -40(%rbp)
movq -40(%rbp), %rcx
addq $32, %rcx
movq %rcx, -24(%rbp)
movl $std::thread::join(), %eax
...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.