当前位置:首页 > C++ > 正文

掌握C++并发利器:future与promise详解(C++异步编程入门指南)

在现代C++开发中,C++ futureC++ promise 是实现C++异步编程C++多线程通信的重要工具。它们允许我们在一个线程中设置值(通过 promise),而在另一个线程中获取该值(通过 future)。本文将从零开始,用通俗易懂的方式带你掌握这两个强大的标准库组件。

什么是 future 和 promise?

想象一下你去餐厅点了一份牛排。服务员给你一张小票(这就像一个 future),告诉你稍后会送来牛排。厨房里的厨师则拿着这张订单准备食物(这就像一个 promise)。当牛排做好后,厨师“兑现承诺”(set value),而你则可以通过小票“获取结果”(get value)。

掌握C++并发利器:future与promise详解(C++异步编程入门指南) C++ future  promise C++异步编程 C++多线程 第1张

基本概念解析

  • std::promise:用于在一个线程中“设置”一个值、异常或状态,作为未来某个操作的结果。
  • std::future:用于在另一个线程中“获取”由 promise 设置的值。它代表一个可能尚未完成的异步操作的结果。
  • 每个 promise 只能关联一个 future,通过 promise.get_future() 获取。

简单示例:基础用法

下面是一个最简单的例子,展示如何使用 promisefuture 在主线程和子线程之间传递数据:

#include <iostream>#include <thread>#include <future>void setValue(std::promise<int>&& prom) {    // 模拟一些耗时操作    std::this_thread::sleep_for(std::chrono::seconds(2));        // 设置值(兑现承诺)    prom.set_value(42);}int main() {    // 创建一个 promise    std::promise<int> prom;        // 从 promise 获取对应的 future    std::future<int> fut = prom.get_future();        // 启动一个新线程,传入 promise    std::thread t(setValue, std::move(prom));        // 主线程可以做其他事情...    std::cout << "等待结果...\n";        // 获取 future 的值(会阻塞直到值被设置)    int result = fut.get();    std::cout << "结果是: " << result << std::endl;        t.join();    return 0;}

在这个例子中:

  1. 我们创建了一个 std::promise<int> 对象 prom
  2. 调用 prom.get_future() 得到一个 std::future<int> 对象 fut
  3. 启动一个新线程,并将 prom 移动过去(因为 promise 不可复制)。
  4. 在子线程中,经过 2 秒延迟后,调用 prom.set_value(42) 设置值。
  5. 主线程调用 fut.get() 等待并获取结果。

处理异常

除了设置正常值,promise 还可以设置异常。这在异步操作出错时非常有用:

void setException(std::promise<int>&& prom) {    try {        throw std::runtime_error("出错了!");    } catch (...) {        // 将当前异常传递给 promise        prom.set_exception(std::current_exception());    }}// 在 main 中:// std::future<int> fut = prom.get_future();// ...// try {//     int result = fut.get(); // 这里会抛出异常// } catch (const std::exception& e) {//     std::cout << "捕获异常: " << e.what() << std::endl;// }

与 async 和 packaged_task 的关系

除了手动使用 promisefuture,C++ 还提供了更高层的抽象:

  • std::async:自动启动异步任务并返回一个 future,内部使用了 promise/future 机制。
  • std::packaged_task:将可调用对象包装成一个任务,调用时自动设置其 future 的值。

但理解底层的 C++ futureC++ promise 机制,有助于你更灵活地设计复杂的C++多线程程序。

注意事项

  • future.get() 只能调用一次,第二次调用会抛出异常。
  • 如果 promise 被销毁但从未调用 set_valueset_exception,则其关联的 future 在调用 get() 时会抛出 std::future_error
  • promise 不可复制,只能移动(move-only)。

总结

C++ futureC++ promise 是 C++11 引入的强大工具,为C++异步编程提供了标准化的解决方案。通过它们,我们可以安全、高效地在线程间传递结果或异常,避免竞态条件和数据竞争。掌握它们的使用,是迈向高级C++多线程编程的重要一步。

希望这篇教程能帮助你轻松理解 future 和 promise!动手写几个小例子,你会掌握得更快。