Day 5:tokio 挑選工具的模式

學習目標

  • 用 tokio::select! 同時等待
  • 計時器與 sleep
  • 處理超時與取消

今日重點

tokio::select!(同時等待多個,誰先完成搶先)

use tokio::time::{sleep, Duration, timeout};

#[tokio::main]
async fn main() {
    tokio::select! {
        _ = sleep(Duration::from_millis(100)) => println!("100ms 到了"),
        _ = sleep(Duration::from_millis(50)) => println!("50ms 先到"),
    }
}

select! 會**並行等待**所有分支,(語義上)第一個完成者執行對應區塊,其他取消。

timeout(限時,怕卡住)

#[tokio::main]
async fn main() {
    let result = timeout(
        Duration::from_millis(100),
        async { sleep(Duration::from_millis(300)).await; "done" }
    ).await;

    match result {
        Ok(value) => println!("OK: {}", value),
        Err(_) => println!("timeout!"),
    }
}

timeout 若超過時間回傳 Err(Elapsed),可安全取消那個 future。

練習

use tokio::time::{sleep, Duration, timeout};

async fn slow_op() -> &'static str {
    sleep(Duration::from_millis(500)).await;
    "slow result"
}

#[tokio::main]
async fn main() {
    // 1. 用 timeout 包住 slow_op,測 200ms -> 應該 timeout
    // 2. 改用 800ms -> 應該成功
    match timeout(Duration::from_millis(200), slow_op()).await {
        Ok(v) => println!("{}", v),
        Err(_) => println!("timeout!"),
    }
}

自我檢查

  • 會用 select! 同時等待
  • 會用 timeout 設限時
  • 知道 select! 的「先到先服務」行為
  • 能處理取消 / 超時

深入連結

  • tokio 官方文件(select, timeout)