Day 1:執行緒基礎

學習目標

  • 用 thread::spawn 建立執行緒
  • 用 join 等待執行緒完成
  • 用 move 閉包捕捉外部變數

今日重點

建立執行緒

use std::thread;
use std::time::Duration;

fn main() {
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("Spawned thread: {}", i);
            thread::sleep(Duration::from_millis(1));
        }
    });

    for i in 1..5 {
        println!("Main thread: {}", i);
        thread::sleep(Duration::from_millis(1));
    }

    handle.join().unwrap();   // 等待 spawn 的執行緒完成
}

thread::spawn 回傳 JoinHandle,可以 .join() 等待。若不 join,主執行緒結束時子執行緒可能沒跑完。

move 閉包(捕捉外部變數)

let name = String::from("Alice");
let handle = thread::spawn(move || {   // move:把 name 搬進執行緒
    println!("Hello from thread: {}", name);
});
// println!("{}", name);  // 錯誤!name 已被搬進 thread
handle.join().unwrap();

閉包要存取外層變數必須 move,因為子執行緒可能比主執行緒活得久。

練習

use std::thread;

fn main() {
    let data = vec![1, 2, 3, 4, 5];

    // 1. 產生一個執行緒,把 data 的和印出來(需 move)
    let handle = thread::spawn(move || {
        let sum: i32 = data.iter().sum();
        println!("Sum: {}", sum);
    });

    handle.join().unwrap();
}
2. 試試不 move 會發生什麼錯誤。

自我檢查

  • 能用 thread::spawn 開執行緒
  • 知道 join() 等待執行緒
  • 懂 move 閉包為什麼需要
  • 了解執行緒執行次序不保證

深入連結

  • The Book 第 16 章「Using Threads to Run Code Simultaneously」