引用来自 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_error
1。没有种族。
1:不保证。技术上未定义的行为。
关于c++ - 在 std::future::unwrap() 和 std::future::get() 中竞赛,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43954868/