Day 2:執行緒技巧與開關
學習目標
- 用執行緒做並行工作
- 收集多個執行緒的結果
- 理解執行緒的開銷與限制
今日重點
收集多個執行緒結果
use std::thread;
fn main() {
let mut handles = vec![];
for i in 0..5 {
let handle = thread::spawn(move || {
i * i // 回傳值
});
handles.push(handle);
}
// 依序 join 並收集結果
let results: Vec<i32> = handles
.into_iter()
.map(|h| h.join().unwrap())
.collect();
println!("{:?}", results); // [0, 1, 4, 9, 16]
}
JoinHandle<T> 的 join 回傳 T,所以執行緒可以「回傳」結果。
執行緒限制與開銷
- OS 執行緒建立有成本(記憶體、context switch)
- 不要為極小工作就開執行緒
- 大量並行任務 → 用執行緒池或 async(第 9 週)
- 主執行緒結束,整支程式就結束(未 join 的子執行緒會被終止)
常用技巧
// 產生固定數量執行緒,各處理不同片段
let workers = 4;
let chunk = 100usize / workers;
// ... 分派工作
練習
use std::thread;
use std::time::Duration;
// 1. 開 3 個執行緒,各 sleep 不同時間回傳自己的編號
// 2. 收集並印出完成順序
fn main() {
let mut handles = vec![];
for i in 0..3 {
handles.push(thread::spawn(move || {
thread::sleep(Duration::from_millis(100 * i));
i
}));
}
for h in handles {
println!("done: {}", h.join().unwrap());
}
}
自我檢查
深入連結
- The Book 第 16 章「Using Threads to Run Code Simultaneously」