c++ - 在 std::future::unwrap() 和 std::future::get() 中竞赛

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

引用来自 n3721 的 C++20 中即将推出的功能的跟进“对 std::future 和相关 API 的改进”

#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_one 还是 th_two


为了澄清我在说什么种族,这里有两种(潜在的)不正当的情况,后者是真正让我感到困惑的情况。

首先是内在未来的设定和展开;未包装的 future 应该作为内部 future 的合适代理,即使实际的 set_value 没有被内部 future 调用。所以 unwrap() 必须返回一个暴露线程安全接口(interface)的代理,而不管另一端发生了什么。

另一种情况是 get() 从 future 发生的事情,当它的代理已经存在于别处时,在这个例子中 inner_fut_unwrap 的代理>inner_fut_get。在这种情况下,谁应该赢得比赛?未包装的 future 或通过调用 get() 在外部 future 获取的 future ?

最佳答案

这段代码让我担心对什么是 futures 和 promises 以及 .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()

所以两个线程都没有“赢得”比赛,因为两个线程实际上都没有机会运行。您链接的文档中的注释,对于 .unwrap(),在第 13 页:

Removes the outer-most future and returns a proxy to the inner future.

所以最外层的 future ,fut_one,是无效的。当您调用 .get() 时,它会抛出 std::future_error1。没有种族。

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

关于c++ - 在 std::future::unwrap() 和 std::future::get() 中竞赛,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43954868/

相关文章:

c++ - 构造 `long double` 右值

c# - "Cartiesian Product"C++ 方法

C++如何将函数应用于 vector 元素

c++ - 他们是否将 copy_if 添加到 c++0x?

c++ - 如何反转 set_value() 和 'deactivate' promise ?

c++ - 谁负责 futures 和 promises 的共享状态

c++ - 在 C/C++ 中查找可用的网络接口(interface)?

macos - 为什么 Xcode 与 Target 成员资格不匹配?

C++11 std::function const 重载歧义

firebase - 按下按钮时如何显示与 FutureBuilder 的对话框?