繁体   English   中英

std::future::get() 或 std::future::wait() 是 std::thread::join() 的替代品吗?

[英]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::futurestd::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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM