Day 4:訊息傳遞進階

學習目標

  • 用 try_recv 非阻塞接收
  • 用 recv_timeout 限時等待
  • 建立 worker 執行緒模式

今日重點

try_recv(非阻塞)

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

let (tx, rx) = mpsc::channel();
thread::spawn(move || {
    thread::sleep(Duration::from_millis(100));
    tx.send(42).unwrap();
});

// 立即檢查,沒有就回 Err
match rx.try_recv() {
    Ok(v) => println!("got {}", v),
    Err(mpsc::TryRecvError::Empty) => println!("還沒到"),
    Err(mpsc::TryRecvError::Disconnected) => println!("對方已關"),
}

recv_timeout(限時)

match rx.recv_timeout(Duration::from_millis(50)) {
    Ok(v) => println!("{}", v),
    Err(_) => println!("等了 50ms 沒有"),
}

worker 模式

let (tx, rx) = mpsc::channel();

// 產生 N 個 worker,各抓一個 job 處理
for id in 0..4 {
    let rx = rx.clone();   // 每個 worker 一個接收端(但 mpsc 只有單一消費…用 Arc<Mutex>)
}

注意:mpsc 是「單一消費」。多 worker 共用 rx 需要用 Arc<Mutex<mpsc::Receiver>>(第 5 天學共享狀態)。

練習

use std::sync::mpsc;
use std::thread;
use std::time::Duration;

fn main() {
    let (tx, rx) = mpsc::channel();

    thread::spawn(move || {
        thread::sleep(Duration::from_millis(30));
        tx.send("slow data").unwrap();
    });

    // 1. 先 try_recv(應該 Empty)
    // 2. 再 recv_timeout 50ms(可能超時)
    println!("{:?}", rx.try_recv());
    println!("{:?}", rx.recv_timeout(Duration::from_millis(200)));
}

自我檢查

  • 會用 try_recv / recv_timeout
  • 理解 mpsc 是單一消費
  • 知道 worker 共用接收需要鎖

深入連結

  • The Book 第 16 章「Using Message Passing」+ std::sync::mpsc 文件