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

Rust中Tokio MPSC通道接收器阻塞问题求助

问题原因

你遇到的阻塞问题,核心在于tokio mpsc通道的关闭机制:只有当所有发送端(Sender)被销毁后,接收端(Receiver)的recv()方法才会返回None,从而退出循环。

你的代码里,main函数中保留了一个Arc<Sender>实例ch_arc——哪怕10个student任务执行完毕并销毁了各自的Sender克隆,这个main持有的Sender依然存活,导致接收端永远不会收到“没有新消息”的信号,teacher函数的循环会一直阻塞等待,程序也就卡在这里。

解决办法

只需要在启动所有学生任务后,主动销毁main中持有的Sender实例,让通道知道不会再有新消息发送即可:

修改后的main函数代码:

#[tokio::main]
async fn main() {
    let (tx, rc): (mpsc::Sender<String>, mpsc::Receiver<String>) = mpsc::channel(100);
    let ch_arc: Arc<mpsc::Sender<String>> = Arc::new(tx);
    
    for i in 0..10 {
        tokio::task::spawn(student(i, ch_arc.clone()));
    }
    // 销毁main持有的Sender实例,触发通道关闭逻辑
    drop(ch_arc);
    let hws = teacher(rc).await;
    println!("{:?}", hws);
}

另外补充一个优化点:tokio::sync::mpsc::Sender本身已经实现了Clone trait,不需要额外用Arc包裹,直接克隆Sender即可简化代码:

async fn student(id: i32, tx: mpsc::Sender<String>) {
    println!("student {} is getting their hw.", id);
    tx.send(format!("student {}'s hw !", id)).await.unwrap();
}

#[tokio::main]
async fn main() {
    let (tx, rc): (mpsc::Sender<String>, mpsc::Receiver<String>) = mpsc::channel(100);
    
    for i in 0..10 {
        tokio::task::spawn(student(i, tx.clone()));
    }
    drop(tx);
    let hws = teacher(rc).await;
    println!("{:?}", hws);
}

这样代码更简洁,逻辑也完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 23:25:22