future 和 promise

内容介绍

std::future 表示“未来会得到的结果”。它适合从异步任务中拿返回值或异常。

常见组合:

  • std::async:直接启动异步任务并返回 future
  • std::promise:手动设置结果。
  • std::packaged_task:把可调用对象包装成带 future 的任务。

async

#include <future>
#include <iostream>
 
int add(int a, int b) {
    return a + b;
}
 
int main() {
    auto fut = std::async(std::launch::async, add, 1, 2);
    std::cout << fut.get() << '\n';
}

get() 会等待结果,并且只能调用一次。

promise

#include <future>
#include <iostream>
#include <thread>
 
int main() {
    std::promise<int> p;
    std::future<int> f = p.get_future();
 
    std::thread t([p = std::move(p)]() mutable {
        p.set_value(42);
    });
 
    std::cout << f.get() << '\n';
    t.join();
}

异常传递

auto fut = std::async(std::launch::async, [] {
    throw std::runtime_error("failed");
    return 1;
});
 
try {
    fut.get();
} catch (const std::exception& e) {
    std::cout << e.what() << '\n';
}

最佳代码实践

  • 需要返回值时优先考虑 std::future
  • 使用 std::async 时指定 std::launch::async,避免实现选择延迟执行。
  • future.get() 只能调用一次,多消费者场景用 std::shared_future
  • 异步任务内部异常应通过 future 或明确日志处理。

常见错误用法

auto fut = std::async(do_work);
// 没有指定 launch 策略,可能延迟到 get 时才执行
auto value1 = fut.get();
auto value2 = fut.get(); // 错误:future 结果只能取一次

注意事项

  • future 是结果通道,不是任务调度系统。
  • 大量任务不要直接无限 async,应使用 cpp线程池
  • promise 必须最终设置值或异常,否则等待方会收到 broken promise。

学习路径