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

时间:2019-11-05 08:10:57

标签: c++ multithreading join future

调用thread.join() / future.get()以后获得的收益后,线程会像future.wait()一样联接吗?我可以仅在将来使用线程而不直接访问该线程吗?

3 个答案:

答案 0 :(得分:2)

  

std::future::get()std::future::wait()可以代替std::thread::join()吗?

不,这些是不同的东西。

std::future是一个同步工具。它是围绕 value 的包装,该包装不是立即可用,而是将可用。它用于通过异步操作(可以在另一个线程中运行)传递数据。在引擎盖下包含一个信号灯,如有需要,get()在上面等待。

另一方面,std::thread代表实际的执行线程。它可以产生多个结果,从而在其生命周期内提供多个std::promise。应该这样做,因为启动和加入线程是一项相对繁重的操作,比等待未来要重得多。这就是为什么应该更喜欢重用线程,将异步操作发布到线程池并等待其结果的原因(std::packaged_task是对此的一种有用的抽象)。

std::future::get()之后,即使设置promise是它所做的最后一件事情,线程也不会立即退出。这些是无关的事件。

答案 1 :(得分:1)

如评论中所述,Linkstd::future没有任何关系。因此,仅在使用std::thread时使用std::thread::join,如果使用std::thread则使用std::future::get / std::future::wait

std::future内部,有一个线程池可以接受作业并以一种聪明的方式分配它。

答案 2 :(得分:1)

在使用future时,您不能100%确定是否创建了实际的新线程。例如,当您使用future执行策略创建std::launch::deferred时,执行是非常串行的。

引用标准:

  

std::launch::deferred:任务在调用线程上执行   第一次请求其结果(延迟评估)


实际上,大多数时候在启动新线程时使用future执行策略创建std::launch::async时。用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
        ...