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

如何在Rust中实现类似Go goroutine的后台函数启动?

在Rust中用Tokio实现非阻塞后台任务(类比Go Goroutine)

在Rust的Tokio异步生态中,你可以用tokio::spawn实现和Go Goroutine类似的非阻塞后台任务效果,直接看修改后的代码:

#[tokio::main]
async fn main() {
    do_something().await;
}

async fn do_something() {
    // 执行当前同步/异步逻辑
    println!("处理do_something中的即时任务");

    // 启动后台任务,不会阻塞当前函数
    tokio::spawn(async move {
        // 后台执行的耗时操作
        println!("启动后台任务");
        // 模拟耗时等待
        tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
        println!("后台任务执行完成");

        // 处理后台任务的错误(避免panic导致程序崩溃)
        if let Err(e) = long_running_task().await {
            eprintln!("后台任务失败: {}", e);
        }
    });

    // 当前函数直接返回,无需等待后台任务
    println!("do_something立即返回");
}

async fn long_running_task() -> Result<(), String> {
    // 模拟可能出错的耗时业务逻辑
    Ok(())
    // 测试错误场景:Err("数据库连接失败".to_string())
}

关键细节说明

  • tokio::spawn的作用:它会把传入的异步任务提交给Tokio的runtime调度,立即返回一个JoinHandle(类似Go里的goroutine句柄),当前函数可以继续执行甚至直接返回,完全不会被后台任务阻塞。
  • move关键字:Rust的所有权系统要求明确变量的生命周期,用move可以把闭包需要捕获的外部变量转移到后台任务中,避免悬垂引用问题。
  • 错误与panic处理:后台任务如果发生未处理的panic,默认会导致整个程序崩溃。所以必须在任务内部处理所有可能的错误(比如用Result和if let),如果需要后续获取任务结果,可以保存JoinHandle并在合适的地方await它来捕获错误。
  • 非抢占式调度:Rust的异步任务是非抢占式的,所以后台任务中必须包含.await点(比如示例中的sleep.await、数据库操作的.await等),让Tokio runtime有机会调度其他任务,否则会阻塞整个runtime。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 05:05:25