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
相关产品推荐
相关产品推荐

