std::async 默认可能延迟执行(std::launch::deferred),需显式指定 std::launch::async 才强制异步启动;future 调用 get()/wait() 后失效,仅可 move 不可 copy;共享结果需用 shared_future;lambda 避免引用捕获以防悬垂。

std::async 启动后不执行?检查 launch 策略
默认情况下 std::async 不一定立刻启动新线程——它可能延迟执行(std::launch::deferred),直到你调用 get() 或 wait() 才在当前线程运行。这常被误认为“没跑起来”。
- 显式指定
std::launch::async强制异步启动:std::async(std::launch::async, func, args...) - 不传策略时行为由实现决定(GCC/Clang 默认可能 deferred,MSVC 倾向 async);跨平台必须写明
- 如果函数有副作用(比如日志、修改全局状态),deferred 模式下
get()之前什么都不会发生
future.get() 阻塞卡死?注意生命周期和 move 语义
std::future 是一次性消费对象:调用 get() 或 wait() 后,它就处于“已取值”状态,再次调用 get() 会抛出 std::future_error(错误码 std::future_errc::no_state)。
- 不能复制
std::future,只能 move;传参或存储时别忘了std::move(fut) - 如果把
future存在容器里(如std::vector<:future>></:future>),push_back 时要std::move,否则编译失败 - 忘记调用
get()或wait()?析构时若结果未取走,且是 async 启动的,会阻塞等待完成——这是隐式同步,容易引发死锁
std::shared_future 怎么共享结果?别直接拷贝 future
一个 std::future 只能被一个所有者取值;想多处等待或多次取值,必须转成 std::shared_future。
- 从
std::future构造:auto sf = fut.share()(fut 之后失效) -
std::shared_future支持拷贝,每个副本都能独立调用get()或wait() - 注意:所有副本共享同一份结果,但
get()对每个副本只生效一次(首次调用返回值,后续调用仍返回该值,不抛错) - 不要对同一个
std::future多次调用share()——第二次会抛std::future_error(no_state)
async + lambda 捕获局部变量?小心悬垂引用和移动陷阱
lambda 传给 std::async 时,按值捕获([=])会拷贝,按引用捕获([&])则危险:原函数栈帧一退,引用就悬垂。
立即学习“C++免费学习笔记(深入)”;
- 避免
[&];改用[=]或显式列出需捕获的变量(如[x, ptr]) - 捕获可移动对象(如
std::string、std::vector)时,lambda 内部实际是拷贝——除非你用std::move在捕获列表中转移:[s = std::move(s)] - lambda 返回类型若依赖捕获变量,记得加
mutable(否则默认 const) - 调试时看到
std::future_error: No associated state,大概率是 future 已被 move 走或 share 过早,而非 lambda 本身问题
std::async 看似简单,但 future 的 move 语义、deferred 启动、以及 lambda 捕获与生命周期的耦合,三者叠在一起就很容易漏掉某一处。










