std::future_status 的三种状态需结合 launch 策略理解:deferred 仅出现在 std::launch::deferred 策略下,表示尚未调度执行;ready 表示共享状态已就绪(值或异常已设置);timeout 表示指定时间内未就绪。

std::future_status 的三种状态含义必须结合 launch 策略理解
std::future_status 本身只是枚举值,不代表“当前任务一定在运行”,它反映的是 std::future 关联的共享状态(shared state)的当前就绪程度。关键在于:只有用 std::launch::deferred 启动的异步任务才可能进入 deferred 状态;默认策略(std::launch::async | std::launch::deferred)下,deferred 很难观察到,除非显式指定。
常见误判是看到 wait_for 返回 deferred 就以为“线程没启动”,其实它只表示“还没被调度执行”,且这个状态仅在调用 get() 或 wait() 时才可能触发执行(lazy evaluation)。
用 wait_for 判断状态时最容易踩的坑
直接循环调用 wait_for 并检查返回值是最常用方式,但要注意:
- 传入的超时时间必须是
std::chrono类型,比如std::chrono::milliseconds(500),不能写500或std::chrono::seconds(0)(后者等价于立即返回timeout) -
wait_for不会改变 future 的内部状态,只是轮询;但get()和wait()会强制“消费”状态,再次调用会抛出std::future_error(错误码为future_errc::no_state) - 如果 future 来自
std::promise且尚未调用set_value或set_exception,wait_for永远不会返回ready
deferred 状态只在特定 launch 策略下出现
想稳定复现 deferred,必须显式使用 std::launch::deferred:
auto fut = std::async(std::launch::deferred, []{ return 42; });
// 此时 fut.wait_for(...) 会立刻返回 deferred
// 直到调用 fut.get() 或 fut.wait(),lambda 才真正执行
而以下写法几乎不会出现 deferred:
auto fut = std::async([]{ return 42; }); // 默认策略,通常走 async 分支
所以判断 deferred 的实际意义,更多是确认“该 future 是否支持延迟求值”,而不是监控任务是否启动。
ready 和 timeout 的边界容易混淆
ready 表示共享状态已设置(无论成功值或异常),不等于“计算已完成”——它可能已被 promise.set_value 主动设值,也可能由 async 自动完成。
timeout 仅说明“在指定时间内未就绪”,不代表失败:后续仍可继续 wait_for 或直接 get() 等待(get() 会永久阻塞直到 ready)。
注意:如果 future 已经 move 走或未绑定任何共享状态(例如默认构造的 std::future<int>{}</int>),wait_for 会直接抛出 std::future_error,错误信息是 std::future_errc::no_state,不是任一 future_status 值。
wait_for 根本不会走到状态判断那一步。C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











