发布于2026-07-11 阅读(0)
扫一扫,手机访问
很多开发者在使用 std::async 时,会下意识以为它默认就是延迟执行——其实不然。必须显式指定 std::launch::deferred,才能真正做到“调用 get() 或 wait() 时才执行函数”。而且每次调用都会重新执行,既不会缓存结果,也不保证线程安全。这个细节一旦忽视,很容易在项目里埋下隐形的坑。

直接调用 std::async 却不传 launch policy 时,行为由实现决定:MSVC 默认 std::launch::deferred,GCC libstdc++ 默认 std::launch::async。这意味着你不能指望“自动延迟”,必须写清楚。
get() 或 wait() 时才真正运行),必须传 std::launch::deferredstd::async(std::launch::async | std::launch::deferred, ...),调度完全由实现决定std::async(std::launch::deferred, []{ return 42; })std::async 返回 std::future,但 std::launch::deferred 模式下,它既不启动线程,也不预分配资源——函数体直到你调用 get()、wait() 或 wait_for() 才执行。这和 std::launch::async 截然不同。
future.get() 会阻塞并立即执行被延迟的函数,返回值future.wait() 阻塞但不取值,仍需后续 get()future.wait_for(...) 在 deferred 模式下永远返回 std::future_status::deferred,因为它根本没在跑,谈不上“等待超时”std::future 析构时若未调用 get() 或 wait(),且是 deferred 模式,不会执行函数,也不会报错——函数就这么丢了std::async 本身没有“延迟 N 秒后执行”的接口。所谓“带延迟的结果”,其实是组合使用:std::launch::deferred + 函数体内手动 sleep,或者用 std::launch::async + 线程内 sleep。两者语义不同。
get() 时才开始计时,适合“用户触发后等几秒再算”场景auto f = std::async(std::launch::deferred, []{ std::this_thread::sleep_for(2s); return "done"; });;之后 f.get() 才真正 sleep 并返回std::chrono::delay_until —— 标准库没有这个函数,容易拼错成 std::this_thread::sleep_until很多人想用 std::async(std::launch::deferred, ...) 实现懒加载或防重入,但要注意:它不保证线程安全,也不缓存结果。每次 get() 都重新执行函数。
get() 会重复触发std::call_once 或 std::once_flag 的替代品std::optional + mutex),std::future 本身不提供该语义get()——无序,不可预测真正难的不是让代码晚点跑,而是搞清“谁在什么时候、以什么方式触发它”。std::launch::deferred 看似简单,但它把执行时机完全交给了 future 的消费者。一旦逻辑分散在多处调用 get(),很容易漏掉某次调用导致函数从未执行,或者重复执行。这种隐式控制流,比显式 sleep + thread 更容易出错。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8