Rust异步编程如何先启动任务后等待以缩短总执行耗时
问题根因
Rust 中async fn返回的Future是惰性执行的:只有被主动轮询(调用.await、被join!/join_all同时轮询、或者被spawn提交给运行时作为独立任务)时,才会真正推进执行逻辑。
你的原代码里,let sleep1 = sleep(5);只是创建了一个Future实例,没有任何轮询操作,所以sleep1根本没有启动计时,直到最后一行sleep1.await才第一次被轮询开始执行。最终执行逻辑完全串行:
- 先等1秒执行完
sleep2 - 再等2秒并行执行完
sleep_arr里的两个任务 - 最后才开始等5秒执行
sleep1
总耗时1+2+5=8秒,和你观测到的结果一致。
修正方案
要让sleep1从流程启动时就开始并行执行,只需要在创建sleep1时就通过async_std::task::spawn把它提交给异步运行时,作为独立任务调度——spawn出去的Future会立刻被执行器推进,不需要等当前流程走到.await才启动。
修正后的完整代码如下:
use async_std::task; use futures::future::join_all; async fn test() -> bool { // spawn后sleep1立刻启动计时,和当前流程并行执行 let sleep1 = task::spawn(sleep(5)); // 执行sleep2,耗时1秒,此阶段sleep1并行运行 sleep(1).await; // 直接将Future传入join_all即可,join_all会同时轮询所有Future实现并行 let sleep_arr = vec![sleep(2), sleep(2)]; // 等待两个2秒任务完成,耗时2秒,此阶段sleep1依然在并行运行 join_all(sleep_arr).await; // 此时累计耗时3秒,sleep1还剩2秒执行完成,等待即可 sleep1.await; true } async fn sleep(sec: u64) -> () { task::sleep(std::time::Duration::from_secs(sec)).await; }
耗时验证
修正后的执行时间线完全符合预期:
- 0秒节点:sleep1启动(需要运行5秒,到第5秒结束)
- 0-1秒:等待sleep2完成,sleep1并行执行,1秒节点sleep2执行完毕,sleep1剩余4秒
- 1-3秒:等待sleep_arr中两个并行的2秒任务完成,sleep1持续并行执行,3秒节点数组内任务全部完成,sleep1剩余2秒
- 3-5秒:等待sleep1剩余任务执行完成
- 总耗时恰好5秒,达到最优效果。
注:如果场景不适合用spawn(比如需要借用短期局部变量,不满足
'static + Send约束),也可以用futures::pin_mut!把sleep1固定在栈上,在每一步await时同时轮询sleep1,但实现会更繁琐,当前示例场景下spawn是最简洁的方案。
内容的提问来源于stack exchange,提问作者frederick
相关产品推荐
相关产品推荐

