You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

运行含无限循环的Rust异步Futures仅执行单个任务的问题排查

Rust异步并发无限循环函数不执行的问题分析与解决

问题根源

Rust的异步执行采用协作式调度模型,执行器不会主动抢占正在运行的Future,必须由当前Future通过await操作主动让出执行权,执行器才会去调度其他待执行的Future。

你写的func_a是无限循环且没有任何await点,执行器启动这个函数后,会一直卡在这个循环里,完全没机会切换到func_b执行。

解决办法

在每个异步函数的循环里加一个主动让出执行权的操作就行,常用的两种方式:

方式1:直接让出执行权

用futures::task::yield_now().await,每次循环都告诉执行器“我先让一让,你去跑别的任务”:

use futures::future::join;
use futures::executor::block_on;
use futures::task::yield_now;

async fn func_a() {
    loop {
        println!("Function A is running");
        // 主动让出执行权,让其他任务有机会执行
        yield_now().await;
    }
}

async fn func_b() {
    loop {
        println!("Function B is running");
        yield_now().await;
    }
}

fn main() {
    let join_handle = join(func_a(), func_b());
    block_on(join_handle);
}

方式2:用异步sleep模拟工作

如果你的实际逻辑里有耗时操作,别用阻塞式的std::thread::sleep(会卡死整个执行线程),要用异步sleep,既能模拟工作耗时,又能让出执行权:

use futures::future::join;
use futures::executor::block_on;
use std::time::Duration;
use futures::future::sleep;

async fn func_a() {
    loop {
        println!("Function A is running");
        // 模拟500毫秒的异步工作,期间执行器可以调度其他任务
        sleep(Duration::from_millis(500)).await;
    }
}

async fn func_b() {
    loop {
        println!("Function B is running");
        sleep(Duration::from_millis(500)).await;
    }
}

fn main() {
    let join_handle = join(func_a(), func_b());
    block_on(join_handle);
}

注意事项

  • 不管用哪种异步运行时(比如Tokio),核心逻辑都是一样的:必须有await点让执行器切换任务。
  • 异步函数里绝对不能用阻塞式操作,不然整个执行线程会被堵死,所有异步任务都停摆。

内容的提问来源于stack exchange,提问作者VoltairePunk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 15:25:10