不想自己 join 一条线程、只想稍后拿到返回值时,用 std::async 提交函数,得到 std::future。f.get() 会等到结果出来(或把任务里抛出的异常在这里重新抛出)。同一 future 只能 get 一次。比手写 thread 短,适合一次性计算。更细的同步仍用上一节的线程与互斥量。时间类型见chrono。

async 与 future

C++ async运行
#include <future>
#include <iostream>

int add(int a, int b) {
    return a + b;
}

int main() {
    std::future<int> f = std::async(std::launch::async, add, 3, 4);
    std::cout << "waiting\n";
    std::cout << f.get() << "\n";  // 等到 add 结束,只能 get 一次
    return 0;
}

输出:

waiting
7

launch 策略

策略行为
std::launch::async在新线程(或等价资源)上马上跑
std::launch::deferred等到 get() / wait() 时在当前线程才跑

不写策略时由实现决定是否新开线程。必须并行就写 std::launch::async。

C++ deferred运行
#include <future>
#include <iostream>

int compute() {
    return 42;
}

int main() {
    auto f = std::async(std::launch::deferred, compute);
    std::cout << f.get() << "\n";  // 这时才执行 compute
    return 0;
}

输出:

42

promise 与 future

一边 set_value,另一边 get。适合自己起的线程里交结果,而不是 async 直接包函数:

C++ promise运行
#include <future>
#include <iostream>
#include <thread>

int main() {
    std::promise<int> prom;
    std::future<int> fut = prom.get_future();
    std::thread worker([&prom]() { prom.set_value(100); });
    std::cout << fut.get() << "\n";
    worker.join();
    return 0;
}

输出:

100

每个 promise 只能设置一次。析构前一直不 set_value,等待的 get 可能永远等下去。

与 thread 怎么选

  • async:一次任务、只要返回值,代码短。
  • thread:长期跑、反复通信、锁和条件变量自己管。

本节说明了 async、future 与 promise 的基本用法。第十章至此收束现代语法与并发入门;可从C++ 是什么起按章回顾,并结合在线编译器继续练习。标准库按头文件查阅见标准库概览。