代码示例
use std::sync::mpsc;
use std::thread;
fn main() {
let (sender, receiver) = mpsc::channel();
// 发送端线程
thread::spawn(move || {
// 这里简单发送一些数据后关闭通道
for i in 0..5 {
sender.send(i).unwrap();
}
});
// 接收端处理
for received in receiver {
println!("Received: {}", received);
}
println!("通道已关闭,优雅退出接收循环。");
}
可能出现的错误类型及避免方法
- 错误类型:
- 如果在发送端未正确关闭通道,接收端调用
recv
或使用 for
循环迭代接收时,可能会导致接收端一直阻塞等待数据,造成死锁。例如,发送端线程意外 panic 而没有正常结束并关闭通道,接收端就会一直等待。
- 避免方法:
- 确保发送端正常关闭:在发送端完成数据发送后,让发送端线程正常结束,这样通道会自动关闭。如示例代码中,发送端线程完成
for
循环发送数据后自然结束,通道随之关闭。
- 使用
try_recv
:可以在接收端使用 try_recv
方法进行非阻塞接收。如果通道关闭且没有数据,try_recv
会返回 Err
,通过检查这个 Err
可以判断通道是否关闭并进行相应处理,不过这种方式需要手动循环检查,没有 for
循环迭代接收那么简洁。例如:
use std::sync::mpsc;
use std::thread;
fn main() {
let (sender, receiver) = mpsc::channel();
thread::spawn(move || {
for i in 0..5 {
sender.send(i).unwrap();
}
});
loop {
match receiver.try_recv() {
Ok(received) => println!("Received: {}", received),
Err(mpsc::TryRecvError::Empty) => {
// 通道未关闭但当前无数据,可选择等待或继续尝试
thread::sleep(std::time::Duration::from_millis(100));
}
Err(mpsc::TryRecvError::Disconnected) => {
println!("通道已关闭,优雅退出接收循环。");
break;
}
}
}
}