对来自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_one
还是th_two
?
为了澄清我在说什么种族,这里有两种(潜在的)种族情况,后者是真正让我感到困惑的情况。
第一个是内在未来的设定和展开;未包装的未来应该作为内部未来的合适代理,即使实际set_value
尚未被调用内部未来。因此unwrap()
,无论另一端发生什么,都必须返回一个公开线程安全接口的代理。
另一种情况是,get()
当它的代理已经存在于其他地方时,来自未来的 a 会发生什么,在这个例子inner_fut_unwrap
中是 的代理 inner_fut_get
。在这种情况下,谁应该赢得比赛?未包装的未来或通过get()
对外部未来的调用获取的未来?