【问题标题】:Is it ok to destroy a std::promise before future.get() is called?在调用 future.get() 之前销毁 std::promise 可以吗?
【发布时间】:2018-01-23 18:16:25
【问题描述】:

我想知道调用 promise.get_future() 是否可以,将未来移动到其他地方(例如,移动到向量中),并可能在调用 future.get() 之前让承诺消失。在以下示例中,调用 gateway->refreshWithCallback 在线程中执行 lambda,以便共享指针可以将 promise 设置为空闲,即使在第二个循环中未调用 future.get(),这似乎有效,但我是生气了!

std::vector<std::future<bool>> futures;
for(GuiGateway *gateway : gateways){
    std::shared_ptr<std::promise<bool>> shared_promise_ptr(new std::promise<bool>());
    futures.push_back(shared_promise_ptr.get()->get_future());
    gateway->refreshWithCallback([shared_promise_ptr](bool success){
        shared_promise_ptr.get()->set_value(success);
    });
}

qDebug() << "waiting for futures";

for(std::future<bool> &future : futures){
    if(future.get() == false){
        qDebug() << "error retrieving all gateway data, aborting auto config";
        return;
    }
}

【问题讨论】:

  • 请注意存在std::make_shared,它在创建将存储在std::shared_ptr 中的新对象时可能更有效(一次性为对象和控制块分配足够的内存)并涵盖有关异常安全的边缘情况。它还可以节省重复,你可以写auto shared_promise_ptr = std::make_shared&lt;std::promise&lt;bool&gt;&gt;();
  • 如果这个问题更简洁一点,我会投票赞成。该示例不必要地具体(因此冗长),您可以使其更简单、更通用。
  • 感谢您的赏金。这当然让我觉得我的贡献受到了赞赏。

标签: c++ concurrency promise future


【解决方案1】:

如果您在销毁 std::promise 之前为其提供值,则关联的 std::future 将能够很好地检索它。它不依赖于仍然存在的std::promise。如果您在销毁之前未能为std::promise 提供值,则尝试从std::future 获取结果将抛出std::future_error,但它的定义也很明确。

【讨论】:

  • 我喜欢这个答案。它抹去了我理解中的一个漏洞。更具体地说:在一个(潜在的)异步函数中,我可以使用本地承诺来解决同步错误路径。 (还)不关心 promise 稍后将进行异步调用。
猜你喜欢
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-13
  • 2017-11-05
  • 2017-10-03
  • 2012-01-30
  • 1970-01-01
相关资源
最近更新 更多