並發與異步模型
學習 Rust 的並發程式設計、異步模型和多執行緒安全,對比 JavaScript 的事件循環機制
並發與異步模型
📖 學習目標
理解 Rust 的並發程式設計模型,包括多執行緒、異步程式設計和執行緒安全機制,對比 JavaScript 的單執行緒事件循環模型。
🎯 執行模型對比
JavaScript 的事件循環
JavaScript 使用單執行緒事件循環模型:
正在加载...
雖然 JavaScript 本身是單執行緒的,但可以透過 Web Workers 實現多執行緒並發,將耗時的計算任務放到後台執行緒執行,避免阻塞主執行緒。這類似於 Rust 的多執行緒,但 Web Workers 之間不能直接共享記憶體,需要透過訊息傳遞進行通訊。
Rust 的多執行緒模型
Rust 支援真正的多執行緒並行執行:
正在加载...
執行模型差異
- 單執行緒 vs 多執行緒: JavaScript 單執行緒事件循環,Rust 支援多執行緒並行
- 並發 vs 並行: JavaScript 並發非並行,Rust 可以真正並行
- 記憶體安全: JavaScript 執行時檢查,Rust 編譯時保證執行緒安全
- 效能: JavaScript 受單執行緒限制,Rust 可以充分利用多核心
🔒 執行緒安全與所有權
共享狀態管理
正在加载...
⚡ 異步程式設計
Rust 的異步程式設計
正在加载...
異步與多執行緒對比
正在加载...
🎯 並發模式對比
JavaScript 的並發模式
正在加载...
Rust 的並發模式
正在加载...
🎯 練習題
練習 1: 執行緒安全計數器
建立一個執行緒安全的計數器,支援多個執行緒同時增加計數:
查看答案
use std::sync::{Arc, Mutex};use std::thread;struct Counter {count: Mutex<i32>,}impl Counter {fn new() -> Self {Counter {count: Mutex::new(0),}}fn increment(&self) {let mut count = self.count.lock().unwrap();*count += 1;}fn get_count(&self) -> i32 {*self.count.lock().unwrap()}}fn main() {let counter = Arc::new(Counter::new());let mut handles = vec![];for _ in 0..10 {let counter = Arc::clone(&counter);let handle = thread::spawn(move || {for _ in 0..100 {counter.increment();}});handles.push(handle);}for handle in handles {handle.join().unwrap();}println!("最終計數: {}", counter.get_count()); // 應該是 1000}
練習 2: 異步任務處理
建立一個異步函數,並發處理多個任務並收集結果:
查看答案
use tokio;use std::time::Duration;async fn process_task(id: i32) -> String {tokio::time::sleep(Duration::from_millis(100)).await;format!("任務 {} 完成", id)}async fn process_all_tasks() -> Vec<String> {let mut handles = vec![];for i in 0..10 {let handle = tokio::spawn(async move {process_task(i).await});handles.push(handle);}let mut results = vec![];for handle in handles {let result = handle.await.unwrap();results.push(result);}results}#[tokio::main]async fn main() {let results = process_all_tasks().await;println!("所有任務完成: {:?}", results);}
練習 3: 生產者消費者模式
實現一個生產者消費者模式,使用通道進行執行緒間通訊:
查看答案
use std::sync::mpsc;use std::thread;use std::time::Duration;fn producer_consumer() {let (tx, rx) = mpsc::channel();// 生產者let producer = thread::spawn(move || {for i in 0..10 {tx.send(format!("產品 {}", i)).unwrap();thread::sleep(Duration::from_millis(100));}});// 消費者let consumer = thread::spawn(move || {for received in rx {println!("消費: {}", received);}});producer.join().unwrap();consumer.join().unwrap();}fn main() {producer_consumer();}
📝 總結
在這一章中,我們學習了 Rust 的並發和異步程式設計:
- 執行模型: Rust 支援真正的多執行緒並行,JavaScript 是單執行緒事件循環
- 執行緒安全: Rust 透過所有權系統在編譯時保證執行緒安全
- 異步程式設計: Rust 的 async/await 語法與 JavaScript 類似
- 並發模式: 使用 Arc、Mutex、RwLock 等型別安全地共享狀態
- 效能選擇: 多執行緒適合 CPU 密集型,異步適合 I/O 密集型
關鍵要點
- Rust 的所有權系統確保執行緒安全
- 異步程式設計提供高性能的 I/O 處理
- 選擇合適的並發模型很重要
- 編譯時檢查避免執行時錯誤
下一步學習
在下一章中,我們將學習 Rust 的型別系統和特徵(Traits),了解如何建構可複用的抽象。
繼續學習: 型別系統與特徵