发布于2026-07-18 阅读(0)
扫一扫,手机访问
先看一个容易被忽略的细节:std::async 如果不显式指定启动策略,你根本没法保证它真的异步。默认行为下,它可能一上来就开新线程执行,也可能拖到你调用 get() 时才同步跑——而且具体选哪种,完全取决于编译器和运行时环境。这可不是什么“平台差异”的小问题,踩过坑的人都知道,线上环境突然变串行、排查半天找不到原因,多半就是这里埋的雷。
显式指定 std::launch::async 才能确保任务真正在新线程中立即执行;默认调用 std::async 不保证异步,可能延迟到 get() 时才同步运行。

标准白纸黑字写得很清楚:只要传入 std::launch::async,实现必须启动新线程执行任务,否则抛出 std::system_error(错误码为 std::errc::resource_una vailable_try_again)。这和“尽量异步”的默认行为完全不同——一个是必须,一个是可能。
future.get() 或 future.wait(),任务在 std::async 返回前就已进入就绪/运行态/proc/sys/kernel/threads-max),直接失败,不会退化为 deferredstd::launch::deferred 不是“轻量异步”,它根本不是异步——函数体完全不执行,直到你调用 future.get() 或 future.wait(),且执行发生在当前线程(即调用 get() 的那个线程)。
get() 时才会真正跑函数,主线程照样卡住deferred future 连续 get() 是串行执行,毫无并发性get() 才触发初始化,行为与普通函数调用一致不显式指定策略时,std::async 接收的是 std::launch::async | std::launch::deferred,这意味着运行时可任意选择一种——而标准未规定选择逻辑,各实现差异极大。
async,但高负载下可能 fallback 到 deferreddeferred表面看两者都要等 get() 拿结果,但阻塞性质完全不同:
async:get() 只是同步等待已完成/进行中的异步任务,主线程可先做其他事deferred:get() 是**触发点+执行点+阻塞点**三合一,函数此时才开始跑,且全程独占当前线程deferred 当成“懒加载异步”,结果发现 UI 线程在 get() 时卡死 200msdeferred,例如配置项解析、简单字符串拼接最易被忽略的一点:std::future 析构时若未调用 get() 或 wait(),对 async 策略会阻塞析构(等待任务结束),而 deferred 则直接丢弃任务——这种静默丢弃可能掩盖逻辑错误。务必确保 future 生命周期可控。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8