在 std::future::unwrap() 和 std::future::get() 中竞争
Race in std::future::unwrap() and std::future::get()
参考 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
?
为了澄清我在说什么种族,这里有两个(潜在的)不雅情况,后者是真正让我感到困惑的情况。
第一种是内在未来的设置和展开;展开的未来应该作为内在未来的合适代表,即使实际的set_value
没有被召唤到内在的未来。 因此,unwrap()
必须返回一个代理,该代理公开线程安全接口,而不管另一端发生什么情况。
另一种情况是当来自未来的get()
在其他地方已经存在代理时会发生什么,在此示例中inner_fut_unwrap
是inner_fut_get
的代理。 在这种情况下,谁应该赢得比赛? 是解开的未来,还是通过呼唤get()
外在的未来而获取的未来?
这段代码让我担心对未来和承诺是什么以及.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()
因此,两个线程都没有"赢得"比赛,因为实际上两个线程都没有机会运行。 请注意您链接的文档,对于第 13 页的.unwrap()
删除最外层的未来,并返回指向内部未来的代理。
所以最外层的未来,fut_one
,是无效的。 当你调用.get()
时,它会抛出std::future_error
1。 没有种族。
1:不保证。 技术上未定义的行为。
相关文章:
- 架构决策:返回std::future还是提供回调
- std::p romise::set_value() 和 std::future::wait() 是否提供内存围栏?
- 修改在 std::future 的 lambda 中引用捕获的值
- 从 T 创建 std::future 的最佳方式<T>
- C++ std::future没有被调用
- 对于等待以 std::future wait() 返回的函数的 CPU 使用率或检查标志在循环中休眠一段时间哪个更好?
- 如何使用 boost::future 重新抛出 std::exception_ptr 存储的原始异常?
- Make zmqpp::socket::connect a std::future
- std::future可以比std::promise活得更长吗
- std::future::get()或std::future::wait()是std::thread::join()的替
- 当 std::future 准备好被检索时发出信号主线程
- C++ std::future 方法应该<T>命名为 is_ready() 还是 ready()?
- 当多次调用时,"std::future::then"的行为是什么?
- 使用 std::vector<std::future<int>> 和 std::async 启动几个线程时中止
- 使用 std::future 的不完整类型无效使用
- 为什么 std::future::wait_for 的行为不符合预期?
- 是什么给了 std::future 一些共享状态
- STD :: Future no_state异常与断言
- std::future<nboth:::Both<int, std::string>> 分段错误
- Using std::future/std::async