std::async 提供异步任务执行,返回 future 获取结果,支持 launch 策略控制线程行为,结合 get/wait 实现同步与异常安全,适用于中小规模并发。

在C++11中,std::async 提供了一种简单而强大的方式来执行异步任务。它能自动创建线程(或延迟执行),并返回一个 std::future 对象,用于获取异步操作的结果。这种方式避免了手动管理线程的复杂性,同时提供了良好的封装性和错误处理机制。
std::async 基本用法
std::async 是一个函数模板,用于启动一个异步任务。它可以接受一个可调用对象(函数、lambda、函数对象等)作为参数,并返回一个 std::future,通过该 future 可以在未来某个时间点获取结果。
基本语法如下:
std::future其中:
立即学习“C++免费学习笔记(深入)”;
-
launch_policy:指定启动策略,可选
std::launch::async(强制异步执行,即创建新线程)或std::launch::deferred(延迟执行,直到调用 get 或 wait);若不指定,则由系统自行决定。 - callable:要异步执行的函数或 lambda 表达式。
- args...:传递给 callable 的参数。
示例:
#include iostream>#include
#include
int compute() {
std::this_thread::sleep_for(std::chrono::seconds(2));
return 42;
}
int main() {
auto fut = std::async(std::launch::async, compute);
std::cout
int result = fut.get(); // 阻塞等待结果
std::cout return 0;
}
std::future 与结果获取
std::future 是一个模板类,代表一个将在未来某个时刻可用的值。它是异步操作结果的“占位符”。
常用方法包括:
- .get():获取结果。一旦结果准备好就返回;否则阻塞当前线程直到结果就绪。注意:每个 future 的 get() 只能调用一次,多次调用会抛出异常。
- .wait():等待异步操作完成,但不获取结果。
- .valid():检查 future 是否持有合法的共享状态(未被 move 或已调用过 get)。
示例:使用 wait 和 get 分离等待与取值
auto fut = std::async([](){std::this_thread::sleep_for(std::chrono::milliseconds(500));
return 100;
});
fut.wait(); // 等待完成
if (fut.valid()) {
std::cout }
异常处理与安全性
异步任务中抛出的异常会被捕获并存储在 shared state 中。当调用 future::get() 时,异常会重新抛出,因此应使用 try-catch 包裹 get 调用。
示例:
auto bad_task = std::async([]{throw std::runtime_error("出错了!");
});
try {
bad_task.get();
} catch (const std::exception& e) {
std::cout }
这样可以安全地处理异步任务中的错误,避免程序崩溃。
任务调度与性能考量
std::async 的实际行为依赖于 launch policy:
- 使用
std::launch::async强制开启新线程,适合必须并发执行的任务。 - 使用
std::launch::deferred则不会立即运行,而是延迟到调用 get 或 wait 时才在当前线程执行,适合可能不需要执行的情况。 - 默认策略(不传 policy)由运行时决定,可能是 async 或 deferred,这可能导致不可预期的行为,特别是在大量使用 async 时可能耗尽线程资源。
建议:
- 对计算密集型任务明确使用
std::launch::async。 - 避免无限制地创建 async 任务,考虑使用线程池或任务队列控制并发数量。
- 注意 future 析构时若仍有关联的异步操作未完成,且为 deferred 策略,则会在析构时同步执行。
基本上就这些。std::async + future 提供了简洁的异步编程模型,适合中小规模的并发需求,理解其行为和限制有助于写出高效可靠的代码。











