Rust 中的并发与多线程:高级技术

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Rust 中的并发与多线程:从基础到进阶技术



Rust 因其所有权模型和类型系统而成为最安全的系统编程语言之一,这可以在编译时防止数据竞争。然而,并发不仅关乎安全,也关乎效率。在本文中,我们将探讨 Rust 中并发与多线程的进阶方面:从基本同步原语到现代异步运行时。本文面向已熟悉 Rust 基础知识的开发者。



1. 安全多线程:Send、Sync 和 Arc<Mutex<T>>



Rust 中安全多线程的基础是两个关键 trait:Send 和 Sync。实现了 Send 的类型可以安全地在线程之间转移。实现了 Sync 的类型可以通过引用在线程之间安全共享。大多数标准类型(例如 i32、String)如果仅包含 Send/Sync 数据,则会自动实现这两个 trait。



对于从多个线程共享访问可变数据,经常使用 Arc<Mutex<T>> 模式。Arc(原子引用计数)允许在线程之间共享所有权,而 Mutex 提供互斥访问。



use std::sync::{Arc, Mutex};use std::thread;

fn main() { let counter = Arc::new(Mutex::new(0)); let mut handles = vec![];

for _ in 0..10 { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += 1; }); handles.push(handle); }

for handle in handles { handle.join().unwrap(); }

println!("Result: {}", *counter.lock().unwrap());}


重要的是要记住:Rust 中的 Mutex 不仅仅是一个锁,而是一个保护数据的容器。获取锁会返回一个智能指针 MutexGuard,它会在超出作用域时自动释放锁。这消除了经典的“忘记解锁”错误。



进阶提示:使用 RwLock 替代 Mutex



如果你的数据经常被读取但很少修改,请使用 RwLock。它允许多个线程同时读取数据,但在至少有一个读取者时会阻塞写入。这可以在“读多写少”的场景下显著提升性能。



use std::sync::RwLock;

let data = RwLock::new(vec![1, 2, 3]);

// 读取 — 多个线程可以同时读取let read_guard = data.read().unwrap();println!("First element: {}", read_guard[0]);drop(read_guard); // 显式释放锁

// 写入 — 独占访问let mut write_guard = data.write().unwrap();write_guard.push(4);


2. 通道:线程间消息传递



通道是共享内存的替代方案。Rust 主要有两种类型的通道:std::sync::mpsc(多生产者、单消费者)和 crossbeam-channel(多生产者、多消费者)。



标准库的 mpsc 非常适合“一个消费者、多个生产者”的场景。它基于队列原则工作:发送方放置消息,接收方按 FIFO 顺序获取消息。



use std::sync::mpsc;use std::thread;

fn main() { let (tx, rx) = mpsc::channel();

let tx1 = tx.clone(); thread::spawn(move || { tx1.send("Message from thread 1").unwrap(); });

thread::spawn(move || { tx.send("Message from thread 2").unwrap(); });

for received in rx { println!("Received: {}", received); }}

博客

书籍推荐