在std :: future :: unwrap()和std :: future :: get()中比赛

时间:2017-05-13 15:31:12

标签: c++ c++11 future unwrap c++20

关于来自n3721"对std :: future和相关API的改进"

的C ++ 20即将推出的功能的后续内容
#include <iostream>
#include <future>
#include <exception>

using std::cout;
using std::endl;

int main() {
    auto prom_one = std::promise<std::future<int>>{};
    auto fut_one = prom_one.get_future();

    std::thread{[prom_one = std::move(prom_one)]() mutable {
        auto prom_two = std::promise<int>{};
        auto fut_two = prom_two.get_future();
        prom_two.set_value(1);
        prom_one.set_value(std::move(fut_two));
    }}.detach();

    auto inner_fut_unwrap = fut_one.unwrap();
    auto inner_fut_get = fut_one.get();

    auto th_one = std::thread{[&]() {
        cout << inner_fut_unwrap.get() << endl;
    }};
    auto th_two = std::thread{[&]() {
        cout << inner_fut_get.get() < endl;
    }};

    th_one.join();
    th_two.join();

    return 0;
}

在上面的代码中,它将赢得打印1的竞赛? th_oneth_two

为了澄清我在谈论的是什么种族,这里有两种(潜在的)活泼的情况,后者是让我感到困惑的情况。

首先是内心未来的设定和展开;未解开的未来应该成为内在未来的合适代理人,即使实际的set_value没有被称为内心的未来。所以unwrap()必须返回一个公开线程安全接口的代理,而不管另一方发生了什么。

另一种情况是,get()来自其他地方的代理已存在于其他地方时会发生什么情况,在此示例中inner_fut_unwrapinner_fut_get的代理。在这种情况下哪个应该赢得比赛?未来的未来或未来是通过致电get()了解未来的未来?

1 个答案:

答案 0 :(得分:1)

这段代码让我担心,对于期货和承诺是什么以及.get()的作用存在某种误解。我们using namespace std;后面有很多std::,这也有点奇怪。

让我们分解吧。这是重要的部分:

#include <iostream>
#include <future>

int main() {
    auto prom_one = std::promise<std::future<int>>{};
    auto fut_one = prom_one.get_future();
    auto inner_fut_unwrap = fut_one.unwrap();
    auto inner_fut_get = fut_one.get();
    // Boom! throws std::future_error()

因此两个线程都没有赢得比赛,因为这两个线程都没有机会运行。请注意您在{p13:

上为.unwrap()链接的文档
  

删除最外面的未来并将代理返回到内在的未来。

因此,最外面的未来fut_one无效。当您致电.get()时,它会抛出std::future_error 1 。没有种族。

1 :不保证。技术上未定义的行为。