【问题标题】:std::async/std::future timeout with partial results带有部分结果的 std::async/std::future 超时
【发布时间】:2020-08-14 16:32:40
【问题描述】:

我想运行一个超时的函数。如果达到超时,我想在超时发生之前访问线程生成的部分结果。

例如,我想在 c++17 中做类似的事情:

std::vector<int> my_result;

auto future = std::async(std::launch::async, [&my_result]() {
    for (int i = 0; i < 100000; i++)
      my_result.push_back(i);
});

auto status = future.wait_for(std::chrono::milliseconds(1));
if (status == std::future_status::timeout) {
    std::cout << "Partial result:" << std::endl;
    for (auto i : my_result)
       std::cout << i << std::endl;
}

做这样的事情安全吗?如果在调用push_back() 期间发生超时,是否保证向量不会处于不一致状态?

如果没有,有没有更好的方法来做到这一点?

【问题讨论】:

    标签: c++ multithreading future


    【解决方案1】:

    绝对不安全。当正在等待的进程尚未完成时会发生超时。 future是纯二进制同步;要么进程完成,结果对象(以及任何副作用)可供接收线程使用,要么进程未完成,nothing 与接收线程同步。因此,尝试从接收线程访问my_result 而不与发送线程同步会导致未定义的行为。

    如果你想得到部分结果,那么这些部分结果的源和目标之间必须有同步。发送者必须决定要公开多少结果,一旦公开,发送者就不能对公开的部分结果中的任何对象做任何事情。任何新结果要么进入不同的对象,要么进入处理源和目标之间的同步切换的对象。同样,接收器必须能够测试部分结果何时准备好并提取它们。

    future 不是这样的 API。您基本上需要某种工作队列式接口,并且两个线程都必须经过特殊编码来处理它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-02
      • 1970-01-01
      • 2020-12-29
      • 1970-01-01
      相关资源
      最近更新 更多