为何异步C++协程中std::async调用的f始终在同一线程运行?
问题原因解析
1. 协程f的执行线程特性
f是一个协程函数,协程的调用规则是:被调用时会同步执行到第一个挂起点才会挂起。而f中仅包含co_return,这是协程的终止操作而非挂起点,因此整个f的函数体都会在调用它的线程中一次性执行完毕,随后返回一个已就绪的std::future<int>。
2. std::async的线程复用导致f始终在同一线程
- 默认策略下,
std::async可能采用std::launch::deferred延迟执行模式:此时f的执行会被延迟到co_await等待future就绪时触发,而这个等待操作发生在主线程,因此f会在主线程执行,线程ID始终不变。 - 即使指定
std::launch::async强制异步,MSVC的std::async底层依赖线程池实现,线程池会复用已创建的线程来执行任务,每次调用f都会复用同一个线程池线程,因此你看到f始终在同一线程运行。
3. g的协程续段在新线程执行的原因
MSVC对co_await std::future的实现逻辑是:当future就绪后,会将协程的续段(即g中co_await之后的代码)提交到线程池调度执行。线程池会为每次续段分配新的线程(或不同的复用线程),因此你会观察到g的续段每次都在不同的新线程中运行。
如果需要让f每次在全新线程执行,可以绕过std::async的线程池,手动使用std::thread创建线程并管理协程执行。
内容的提问来源于stack exchange,提问作者Angle.Bracket
相关产品推荐
相关产品推荐

