并发与异步模型
学习 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),了解如何构建可复用的抽象。
继续学习: 类型系统与特征