Tokio异步任务为何按8个批次执行?单线程认知困惑
问题代码
use tokio::task; use std::thread; #[tokio::main] async fn main() { for _i in 0..200 { task::spawn(async move { for _j in 0..1000000000 { } println!("{}",_i); }); } for _j in 0..1000000000 { } println!("HELLO FROM MAIN THREAD !!!"); }
现象原因解析
你看到任务按8个一批执行,核心原因是Tokio默认的Runtime是多线程模式,而非单线程:
#[tokio::main]宏默认初始化的是多线程Runtime,它会根据你的CPU核心数创建对应数量的工作线程(比如8核CPU就会生成8个工作线程)。- 你代码里的异步任务本质是同步阻塞任务:任务内部的大循环没有任何异步等待(
await)操作,会一直占用当前工作线程直到循环结束。多线程Runtime下,8个工作线程可以同时处理8个这样的阻塞任务,所以你会看到8个任务同时输出结果;当某个任务完成后,Runtime会从任务队列取下一个任务执行,表现为一批一批的输出。
如果想要验证单线程Runtime的串行执行行为,可以修改#[tokio::main]为单线程 flavor:
#[tokio::main(flavor = "current_thread")] async fn main() { // 原代码逻辑不变 }
此时所有任务都会在同一个线程里串行执行,你会看到任务一个接一个输出结果。
另外补充:Tokio的多线程Runtime设计是为了高效处理大量异步任务,对于这种纯阻塞的CPU密集型任务,更推荐使用tokio::task::spawn_blocking提交,让Runtime把这类任务放到专门的阻塞线程池处理,避免占用工作线程影响其他异步任务的调度。
内容的提问来源于stack exchange,提问作者Shivam Varshney
相关产品推荐
相关产品推荐

