std::future 与临时 std::promise

问题描述 投票:0回答:2

我无法理解 Promise 如何与 future 配合。 我有一个返回

std::future
的函数,如下例所示:

std::future<int> calcSomeValue() {
}

我的问题是,这个 future 可以通过异步计算生成线程,或者可以有一个已经准备好返回的结果,所以我希望使用

std::promise
返回它而不运行线程。但是...我不知道这是否安全或者我还能做什么。 参见示例:

std::future<int> calcSomeValue() {
    if (resultIsReady()) {
        std::promise<int> promise; // on the stack
        std::future<int>  rv = promise.get_future(); // is future part of the memory occupied by promise?

        promise.set_value(resultThatIsReady); // does it store the value in promise or in future?
        return rv; // <--- What will happen when promise is lost?
    }
    else {
        return std::async(....)
    }
}

请参阅上面代码中的注释。 当调用

.get()
时,Future 是否会访问 Promise 变量,其中 Promise 已经实现?如果是的话我会在这里大闹一场。

任何人都可以告诉我在这种特殊情况下如何返回

std::future

c++ promise std future
2个回答
4
投票

promise
-对象与共享状态相关联(注意“共享”)。当调用
promise::get_future
时,您将收到一个
future
- 对象,该对象与与相应 Promise 对象关联的共享状态相同。这种状态至少会随着一个关联的生产者(即承诺)或消费者(即未来)的存在而存在。因此,
promise
的生命周期是否在相应的
future
对象之前结束并不重要。

不规范,但请参阅 cplusplus.com 上描述的 promise

共享状态的生命周期至少持续到最后一个对象 与其关联的对象将其释放或销毁。因此它 可以使最初获得它的 Promise 对象存活下来,如果 也与未来相关。


0
投票

为了澄清 OP 的困境 - 当设置值的 Promise 已被释放时,在 future 上调用 get 是否安全? - 理解共享状态的概念很重要。 Scott Meyers 在《Effective Modern C++》一书中的 Item 38 对此进行了解释。

...未来是沟通渠道的一端,通过该渠道, 被调用者将结果传输给调用者。被调用者(通常运行 异步)将其计算结果写入 通信通道(通常通过 std::promise 对象),以及 调用者使用 future 读取该结果。 ...被调用者的结果是 存储在...共享状态。共享状态通常是 由基于堆的对象表示,但它的类型、接口和 本标准未规定实施方式。标准库 作者可以自由地以他们喜欢的任何方式实现共享状态。

书中的图表。

Shared State +----------+ std::future +-----------+ std::promise +--------+ | Caller |<----------------+ Callee's |<---------------------+ Callee | +----------+ | Result | (typically) +--------+ +-----------+

这里有一些要点,指出了需要掌握的重要概念。

被调用者是调用者线程调用的异步函数
  • Promise 和 future 是调用者和被调用者之间通信通道的两端
  • 承诺是共享状态的编写者,而未来是读者
  • 被调用者生成的结果不能存储在被调用者中,因为当调用者尝试检索它时,被调用者的范围可能会丢失
  • 被调用者生成的结果不能存储在调用者中,因为调用者的 future 可以复制为shared_futures,但结果可能不可复制
  • 需要一个单独的共享状态实体来跨副本提供明确唯一的稳定存储位置
  • 共享状态通常在堆上以依赖于平台的方式实现
  • 它通常使用引用计数来跟踪 future 和引用它的承诺
  • 当没有 Future 或 Promise 引用它时,它就会被清理
  • 它被释放最后一个引用的线程清理
  • 您可以在
共享状态标准规范

中阅读更多详细信息

© www.soinside.com 2019 - 2024. All rights reserved.