std :: async / std :: future超时并显示部分结果

问题描述

我想运行一个带有超时的函数。而且,如果达到了超时时间,我希望可以访问线程在超时发生之前生成的部分结果。

作为一个例子,我想在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()期间发生超时,是否可以保证引导程序不会处于不一致状态?

如果没有,还有更好的方法吗?

解决方法

绝对不安全。当等待的进程尚未完成时,发生超时。 future是纯二进制同步;或者该过程已完成并且结果对象(以及任何副作用)可用于接收线程,或者该过程未完成并且没有同步到接收线程。因此,尝试从接收线程访问my_result而不与发送线程同步会导致行为不确定。

如果要获得部分结果,则这些部分结果的源和目标之间必须存在同步。发送者必须决定要公开多少个结果,一旦公开,发送者就不能对公开的部分结果中的任何对象做任何事情。任何新结果要么进入另一个对象,要么进入处理源和目标之间的同步切换的对象。同样,接收者必须能够测试部分结果准备就绪的时间并提取出来。

future并非类似API的API。基本上,您需要某种工作队列样式的接口,并且必须对两个线程进行特殊编码才能对其进行处理。