c++ - 我们什么时候需要 std::shared_future 而不是 std::future 来进行线程间同步?

标签 c++ c++11 promise future shared

我尝试测试 std::shared_future 如何在不同线程之间共享,因为这些线程都调用其 wait() 函数,并在其 后唤醒调用信号。如下:

#include <iostream>
#include <future>
using namespace std;
int main() {
    promise<void> p, p1, p2;
    auto sf = p.get_future().share(); // This line
    auto f1 = [&]() {
        p1.set_value();
        sf.wait();
        return 1;
    };
    auto f2 = [&]() {
        p2.set_value();
        sf.wait();
        return 2;
    };
    auto ret1 = async(launch::async, f1);
    auto ret2 = async(launch::async, f2);
    p1.get_future().wait();
    p2.get_future().wait();
    p.set_value();
    cout << ret1.get() << ", " << ret2.get();
    return 0;
}

程序打印 1, 2 并且工作正常。

然后我使用 oridinay auto sf = p.get_future().share(); 行更改为 auto sf = p.get_future() future 对象,而不是shared 版本,编译并运行。我得到了相同的结果:虽然我预计对于非共享版本,只有 1 个线程将成功等待并返回,而其他线程将挂起。但看起来程序仍然运行正常。

所以我的问题是:我们什么时候需要使用 std::shared_future 而不是 std::future?或者它只是像 std::shared_ptr 这样的对象,作为 std::future 的简单包装,以便可以传递?

我的意思是,在任何情况下,非共享 future 都不能满足需求或场景。能帮忙解释一下吗?

最佳答案

shared_future的“共享”部分重要的不是等待,而是得到

I expected that for the non-shared version, only 1 thread will successfully wait and return while other threads will hang.

不,这是完全安全的,您可以根据需要从任意多个线程等待 future (它是 const 成员,因此是线程安全的),并且在设置结果时所有线程都必须解除阻塞。但请注意 wait()有人调用 get() 后无法再调用.

区别在于获得结果的方式。请记住,std::future代表 std::promise 设定的 future 结果.

  • std::future::get()按值返回。它只能被调用一次,因此只能从一个线程调用。
  • std::shared_future::get()返回常量引用。它可以从多个线程多次调用。当然要小心底层对象的线程安全性——它的方法是否真的是线程安全的。

此外std::shared_future可以被克隆,并且多个此类对象可以引用单个共享状态,即链接到单个 promise 对象。只要有一些 future/promise 指向它,共享状态就存在,比如 std::shared_ptr<State> .

就您而言,您稍微误用了 std::shared_future sf ,每个等待结果的线程都应该得到自己的克隆。这样,它的生命周期就是安全的。设想的工作流程是:

  • std::promise创建后,[第一个] future从中获得。
  • promise 是给生产者的,消费者并不知道。
  • future 被赋予[每个]消费者[他们可以克隆它并在必要时传递它]。

I mean is there any case that non-shared future doesn't fulfill the need or scenario. Would you help to explain?

有两个消费者线程,都在等待结果。 std::future需要一个线程来调用 get并以某种方式与他人分享该结果。尽管两者都可以调用 wait() 。另一方面std::shared_future允许两者“查看”结果,因为它是常量。是的,如果需要传递结果,就必须复制结果,但无论如何这是不可避免的。

关于c++ - 我们什么时候需要 std::shared_future 而不是 std::future 来进行线程间同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73835444/

相关文章:

c++ - 通用模板函数总是返回整数值

c++ - 异常安全和 make_unique

c++ - 如何从 istream 的开头可移植地获取以字节为单位的偏移量?

javascript - 然后在里面调用异步函数

c++ - 为什么switch语句不能应用于字符串?

c++ - 套接字配置中的 TCP 重传

c++ - 将模板参数插​​入 ostream

c++ - CUDA 结合 OpenMP

javascript - jQuery: promise : 'always()' 未执行

android - 在 RxJava 中将 Singles 链接在一起