std::async是C++11引入的轻量级异步机制,返回future用于取结果或等待;支持async(新线程立即执行)和deferred(调用get/wait时同步执行)策略,默认由实现决定,建议显式指定。

std::async 是 C++11 引入的轻量级异步启动机制,用来“扔一个任务去后台跑”,并立即返回一个 std::future 对象,用于后续取结果或等待完成。它不直接管理线程,而是由运行时决定是新开线程执行,还是延迟到 future.wait()/get() 时才同步执行(取决于 launch 策略)。
基本用法:启动异步任务并获取结果
最常用形式是传入可调用对象(函数、lambda、bind 等)和参数,返回 future:
#include#include int compute(int x) { return x x + 2 x + 1; }
int main() { // 启动异步计算,auto 推导为 std::future
auto fut = std::async(std::launch::async, compute, 5); // 做其他事…… std::cout << "busy work...\n"; // 阻塞等待结果(若未完成),然后取值 int result = fut.get(); // 输出 36(5² + 2×5 + 1) std::cout << "result = " << result << "\n";}
立即学习“C++免费学习笔记(深入)”;
注意:fut.get() 只能调用一次;调用后 future 失效;若任务抛异常,get() 会重新抛出。
两种 launch 策略:async vs deferred
std::launch 是枚举类型,控制任务何时/如何执行:
- std::launch::async:强制在新线程中立即启动任务(真正并发)
-
std::launch::deferred:懒加载——不立刻执行,只在调用
wait()或get()时,以同步方式在当前线程执行(无并发,但避免过早计算) - 默认策略是
std::launch::async | std::launch::deferred,由实现决定选哪个(常见实现优先 async,除非资源紧张)
建议显式指定策略,避免行为不确定。例如想确保并发,就写 std::async(std::launch::async, ...)。
future 的三种等待方式
除了 get()(取值+阻塞+释放 future),还可:
- wait():仅阻塞等待完成,不取值,适合“等做完就行”
-
wait_for(duration):带超时等待,返回
std::future_status(ready / timeout / deferred) - wait_until(time_point):等待到指定时间点
示例:
auto fut = std::async(std::launch::async, []{
std::this_thread::sleep_for(2s);
return 42;
});
if (fut.wait_for(1s) == std::future_status::timeout) {
std::cout << "still running...\n";
}
// 再等一次,或直接 get()
std::cout << fut.get() << "\n"; // 输出 42
async 不是万能的:适用场景与注意事项
std::async 简单易用,但有隐含成本和限制:
- 每次调用都可能创建新线程(尤其 async 策略下),频繁调用易导致线程爆炸——适合“粒度较大”的任务,而非循环里每轮都 async
- 无法主动取消任务(C++20 前无标准取消机制)
- future 析构时若未调用
get()或wait(),且任务是 async 模式,析构会**阻塞等待完成**(易引发意外卡顿!) - 如需更精细控制(共享状态、多生产者、手动调度),应转向
std::promise+std::future组合,或使用线程池、第三方库(如 folly、boost.asio)
简单任务用 async 足够;复杂并发逻辑,别硬套 async,该上 promise 就上。
基本上就这些。std::async 是入门并发的好跳板,理解它怎么和 future 协作,就踩稳了 C++ 异步的第一步。











