简体   繁体   English

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

[英]When do we need std::shared_future instead of std::future for inter-thread synchronization?

I tried to test how std::shared_future is shared between different threads as these threads all calls its wait() function, and wake up after its signal is called.我尝试测试std::shared_future如何在不同线程之间共享,因为这些线程都调用其wait() function,并在其signal被调用后唤醒。 As below:如下:

#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;
}

The program prints 1, 2 and works fine.该程序打印1, 2并且工作正常。

Then I changed the line of auto sf = p.get_future().share();然后我改变了auto sf = p.get_future().share();这行into auto sf = p.get_future() using oridinay future object, not the shared version, compile and run.进入auto sf = p.get_future()使用 oridinay future object,而不是shared版本,编译并运行。 I got the same result: while I expected that for the non-shared version, only 1 thread will successfully wait and return while other threads will hang.我得到了相同的结果:虽然我预计对于非共享版本,只有 1 个线程将成功wait并返回,而其他线程将挂起。 But seems still the program runs OK.但似乎程序仍然运行正常。

So my question is: when do we need to use std::shared_future instead of std::future ?所以我的问题是:我们什么时候需要使用std::shared_future而不是std::future Or it's just an object like std::shared_ptr , as a simple wrapper of std::future so that it could be passed around?或者它只是一个像std::shared_ptr的 object,作为std::future的简单包装,以便它可以传递?

I mean is there any case that non-shared future doesn't fulfill the need or scenario.我的意思是,在任何情况下,非共享的未来都不能满足需求或场景。 Would you help to explain?你能帮忙解释一下吗?

The "shared" part of shared_future is not about the waiting but getting . shared_future的“共享”部分不是等待而是获取

I expected that for the non-shared version, only 1 thread will successfully wait and return while other threads will hang.我预计对于非共享版本,只有 1 个线程会成功等待并返回,而其他线程会挂起。

No, this is completely safe, you can wait on a future from as many threads as you want (it is a const member, hence thread-safe) and all must unblock when the result is set.不,这是完全安全的,您可以从任意数量的线程中等待未来(它是一个 const 成员,因此是线程安全的),并且在设置结果时都必须解除阻塞。 But be warned that wait() cannot be called after someone called get() .但请注意,在有人调用get()之后不能调用wait() ) 。

The difference is in how you get the results.不同之处在于您如何获得结果。 Remember, std::future stands for a future result set by std::promise .请记住, std::future代表由std::promise设置的未来结果。

  • std::future::get() returns by value. std::future::get()按值返回。 It can only be called once and thus only from one thread.它只能被调用一次,因此只能从一个线程调用。
  • std::shared_future::get() returns a const reference. std::shared_future::get()返回一个常量引用。 It can be called many times from multiple threads.它可以从多个线程中多次调用。 Of course be careful about the thread-safety of the underlying object - whether its methods are really thread-safe.当然要小心底层 object 的线程安全——它的方法是否真的是线程安全的。

Furthermore std::shared_future can be cloned and multiple such objects can refer to a single shared state, ie linked to a single promised object.此外,可以克隆std::shared_future shared_future 并且多个此类对象可以引用单个共享 state,即链接到单个承诺的 object。 The shared state exists as long as some future/promise points to it, like std::shared_ptr<State> .只要某些未来/承诺指向它,共享的 state 就存在,例如std::shared_ptr<State>

In your case, you are slightly misusing std::shared_future sf , each thread that awaits the result should get its own clone.在您的情况下,您稍微滥用了std::shared_future sf ,等待结果的每个线程都应该获得自己的克隆。 That way, its lifetime is safe.这样,它的生命周期是安全的。 The envisioned workflow is:设想的工作流程是:

  • std::promise is created, the [first] future is obtained from it. std::promise被创建,[第一个] future是从中获得的。
  • The promise is given to the producer, consumers do not know about it. promise给生产者,消费者不知道。
  • The future is given to [each] consumer [which can clone it and pass it along if necessary].未来被赋予[每个]消费者[可以克隆它并在必要时传递它]。

I mean is there any case that non-shared future doesn't fulfill the need or scenario.我的意思是在任何情况下非共享未来都不能满足需求或场景。 Would you help to explain?你能帮忙解释一下吗?

Having two consumer threads, both awaiting the result.有两个消费者线程,都在等待结果。 std::future would require for exactly one thread to call get and somehow share that result with the other. std::future将需要一个线程调用get并以某种方式与另一个线程共享该结果。 Although both could have called wait() .尽管两者都可以调用wait() On the other hand std::shared_future allows both to "view" the result since it is const.另一方面, std::shared_future允许两者都“查看”结果,因为它是 const。 Yes, one has to copy the result if it needs to be passed around but that is unavoidable anyway.是的,如果需要传递结果,则必须复制结果,但无论如何这是不可避免的。

One copy of std::shared_future cannot be used from different threads except for copying. std::shared_future 的一份副本不能从不同的线程使用,除了复制。 It is necessary that each thread has its own copy of std::shared_future.每个线程都有自己的 std::shared_future 副本是必要的。

https://en.cppreference.com/w/cpp/thread/shared_future https://en.cppreference.com/w/cpp/thread/shared_future

Access to the same shared state from multiple threads is safe if each thread does it through its own copy of a shared_future object.如果每个线程都通过自己的 shared_future object 副本访问同一个共享 state,那么它是安全的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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