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

显式指定 std::launch::async 才能确保任务真正在新线程中立即执行;默认调用 std::async 不保证异步,可能延迟到 get() 时才同步运行。

C++ async异步执行任务 _ launch::async与deferred区别【详解】

std::launch::async 强制创建线程的硬性要求

标准白纸黑字写得很清楚:只要传入 std::launch::async,实现必须启动新线程执行任务,否则抛出 std::system_error(错误码为 std::errc::resource_una vailable_try_again)。这和“尽量异步”的默认行为完全不同——一个是必须,一个是可能。

std::launch::deferred 是纯同步延迟,零线程开销

std::launch::deferred 不是“轻量异步”,它根本不是异步——函数体完全不执行,直到你调用 future.get()future.wait(),且执行发生在当前线程(即调用 get() 的那个线程)。

默认策略(async | deferred)为什么危险

不显式指定策略时,std::async 接收的是 std::launch::async | std::launch::deferred,这意味着运行时可任意选择一种——而标准未规定选择逻辑,各实现差异极大。

get() 调用时机对 async 和 deferred 的实际影响

表面看两者都要等 get() 拿结果,但阻塞性质完全不同:

最易被忽略的一点:std::future 析构时若未调用 get()wait(),对 async 策略会阻塞析构(等待任务结束),而 deferred 则直接丢弃任务——这种静默丢弃可能掩盖逻辑错误。务必确保 future 生命周期可控。

本文转载于:https://www.php.cn/faq/2344342.html 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。