为何tokio::spawn未执行全部代码?Rust异步任务问题排查
问题原因
你的代码里,main函数在循环生成完所有Tokio异步任务后就直接执行结束了。Tokio运行时的规则是:当作为根任务的main函数终止时,会立刻停止所有未完成的子任务,不会等待它们执行完毕。
这就导致只有少数任务能在main退出前抢到CPU时间片完成输出,剩下的任务还没来得及运行就被强制终止,所以你只能看到部分数字输出。
解决办法
要让所有任务都执行完成,需要收集每个tokio::spawn返回的JoinHandle,然后等待所有任务结束。常用两种方式:
方式一:使用join_all(适合批量任务)
先在Cargo.toml中添加futures = "0.3"依赖,然后收集任务句柄并等待:
use futures::future::join_all; #[tokio::main] pub async fn main() { let mut task_handles = Vec::new(); for i in 1..10 { let handle = tokio::spawn(async move { println!("{}", i); }); task_handles.push(handle); } // 等待所有任务执行完成 join_all(task_handles).await; }
方式二:使用tokio::join!(适合任务数量固定且较少的场景)
直接显式等待每个任务的句柄:
#[tokio::main] pub async fn main() { let h1 = tokio::spawn(async { println!("1") }); let h2 = tokio::spawn(async { println!("2") }); let h3 = tokio::spawn(async { println!("3") }); let h4 = tokio::spawn(async { println!("4") }); let h5 = tokio::spawn(async { println!("5") }); let h6 = tokio::spawn(async { println!("6") }); let h7 = tokio::spawn(async { println!("7") }); let h8 = tokio::spawn(async { println!("8") }); let h9 = tokio::spawn(async { println!("9") }); tokio::join!(h1, h2, h3, h4, h5, h6, h7, h8, h9); }
补充说明:Tokio的任务调度是抢占式的,所以即使等待所有任务完成,输出顺序依然是随机的,这和你最初的预期一致。
内容的提问来源于stack exchange,提问作者lucian
相关产品推荐
相关产品推荐

