我想运行一个超时的函数。如果达到超时,我想在超时发生之前访问线程生成的部分结果。
例如,我想在 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()
期间发生超时,是否有保证? vector 不会处于不一致的状态吗?如果没有,有没有更好的方法来做到这一点?
最佳答案
这绝对不安全。当正在等待的进程尚未完成时会发生超时。 future
是纯二进制同步;要么进程完成并且接收线程可以使用结果对象(以及任何副作用),要么进程不完整并且没有任何内容与接收线程同步。因此,尝试访问 my_result
来自接收线程而不与发送线程同步会导致未定义的行为。
如果您想获得部分结果,那么这些部分结果的源和目标之间必须有同步。发送者必须决定要公开多少结果,一旦公开,发送者就不能对公开的部分结果中的任何对象做任何事情。任何新结果要么进入不同的对象,要么进入处理源和目标之间的同步切换的对象。同样,接收器必须能够测试部分结果何时准备好并提取它们。future
不是这样的 API。您基本上需要某种工作队列样式的接口(interface),并且两个线程都必须经过特殊编码才能处理它。
关于c++ - 带有部分结果的 std::async/std::future 超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63416688/