Day 3:訊息傳遞(mpsc 通道)
學習目標
- 用 mpsc::channel 建立通道
- 在執行緒間傳遞訊息
- 用 Receiver 迭代接收
今日重點
單一發送者
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel(); // tx: 發送端, rx: 接收端
thread::spawn(move || {
tx.send(String::from("hello")).unwrap();
tx.send(String::from("from thread")).unwrap();
});
// 接收端可用迭代方式收到所有訊息
for received in rx {
println!("Got: {}", received);
}
}
mpsc= **m**ulti-**p**roducer, **s**ingle-**c**onsumer。多個發送者、單一接收者。
多個發送者(clone tx)
let (tx, rx) = mpsc::channel();
for i in 0..5 {
let tx_clone = tx.clone();
thread::spawn(move || {
tx_clone.send(format!("Message {}", i)).unwrap();
});
}
drop(tx); // 關閉原始發送端
// 所有 tx 都 drop 後,迭代才會結束
for received in rx {
println!("Received: {}", received);
}
必須 clone 之後把**所有** tx(含原始)都 drop,接收端的
for才會在收完後結束,否則會永遠 block 等待。
練習
use std::sync::mpsc;
use std::thread;
fn main() {
let (tx, rx) = mpsc::channel();
// 1. 一個執行緒依序發送 "a", "b", "c"
thread::spawn(move || {
for msg in ["a", "b", "c"] {
tx.send(msg).unwrap();
}
});
// 2. 主執行緒迭代接收
for msg in rx {
println!("{}", msg);
}
}
自我檢查
- 知道 mpsc 的全名
- 會建立通道與 send / iter
- 知道要 drop 所有發送端迭代才會結束
- 理解訊息傳遞是安全並發的好方法
深入連結
- The Book 第 16 章「Using Message Passing to Transfer Data Between Threads」