必须通过std::future的get()或wait()获取结果或等待完成,否则可能阻塞析构;支持async、deferred及二者组合策略,future为单次使用,异常被捕获并重抛,shared_future允许多次读取。

用 std::async 启动异步任务后,必须通过 std::future 获取结果或等待完成;不调用 get() 或 wait() 可能导致线程资源未释放、程序阻塞在析构时。
std::async 的三种启动策略
std::async 支持三种 std::launch 策略,决定任务何时执行:
- std::launch::async:强制新线程立即执行(真正异步)
-
std::launch::deferred:延迟执行,直到调用
future.get()或future.wait()时才在当前线程运行(类似惰性求值) - std::launch::async | std::launch::deferred(默认):由标准库决定——通常优先异步,但可能退化为延迟执行(尤其系统负载高时)
显式指定策略更可控。例如:auto f = std::async(std::launch::async, []{ return 42; });
future 的核心操作:get() 与 wait()
std::future 是单次使用的同步原语,关键行为如下:
立即学习“C++免费学习笔记(深入)”;
-
get():阻塞等待结果,返回值(或抛出异常),且只能调用一次;第二次调用会抛出std::future_error -
wait():仅阻塞等待完成,不取值,可多次调用(但无实际意义) -
wait_for()和wait_until():带超时的等待,返回std::future_status(ready/timeout/deferred)
注意:即使任务已结束,get() 仍会移动内部存储的值或异常,之后 future 处于无效状态。
处理异常和共享状态
异步函数内抛出的异常不会崩溃程序,而是被捕获并存入 future 中:
- 调用
get()时,若任务抛过异常,该异常会被重新抛出(类型不变) - 多个
future可通过std::shared_future共享同一结果(适用于多处读取场景) -
std::shared_future支持多次get(),需由future.share()转换获得
示例:auto sf = f.share(); auto a = sf.get(); auto b = sf.get(); // 合法
生命周期管理要点
std::future 析构时,若关联的异步任务仍在运行且策略为 async,析构会阻塞直到任务完成——这是常见陷阱:
- 避免临时
future:如std::async(...).get();会立刻阻塞,失去异步意义 - 确保
future对象存活到你准备取结果时;推荐用命名变量持有 - 若需“只管启动、不关心结果”,可用
std::async(std::launch::async, ...);(但注意析构仍会等)
真正“fire-and-forget”应配合 std::thread + 分离,或封装成不返回 future 的接口。











