本页目录
线程与同步原语
Rust 标准库的并发工具箱——Mutex/RwLock 提供共享可变访问,mpsc channel 在线程间传递消息(不共享内存),Condvar 做条件等待,atomics 和 Ordering 是无锁并发的根基。每个工具对应一种"线程间传递信息"的模式。
std::thread
let handle = spawn;
handle.join.unwrap; // 等待线程结束
每个线程有独立栈(Linux 默认 2MB,可通过 Builder::stack_size 调整)。std::thread::spawn 的闭包必须 Send + 'static——线程可能比 spawner 活得久。
Mutex: 互斥锁
use Mutex;
let m = new;
* m.lock.unwrap += 1; // lock() 返回 MutexGuard
// MutexGuard drop → 自动 unlock (即使有 panic, unwinding 也会 drop)
MutexGuard<'_, T> 实现了 DerefMut(给你 &mut T)和 Drop(释放锁)。不需要手动 unlock()。如果持锁线程 panic,Mutex 被"poisoned"——后续 lock() 返回 Err(PoisonError),让你知道数据可能处于不一致状态。
RwLock: 读写锁
use RwLock;
let lock = new;
let r1 = lock.read.unwrap; // 共享读锁
let r2 = lock.read.unwrap; // 多个 reader 共存
// let w = lock.write().unwrap(); // WOULD BLOCK: readers active
drop; drop; // readers gone
let mut w = lock.write.unwrap; // 现在可以写
RwLock 适用于读多写少。但要注意:如果 reader 持续不断,writer 可能饿死。std::sync::RwLock 不保证公平性(非 FIFO)——具体行为取决于操作系统调度器。
mpsc: 多生产者单消费者 channel
use mpsc;
let = channel;
spawn;
let msg = rx.recv.unwrap; // 阻塞等待
recv() 阻塞当前线程直到有消息——这不是 async。async 场景用 tokio::sync::mpsc。当所有 tx 被 drop 时,rx.recv() 返回 Err(RecvError)——这点很重要:channel 的"关闭"是通过 sender 的 Drop 隐式传达的。
Condvar: 条件变量
use ;
let pair = new;
// 等待线程:
let = &*pair;
let mut guard = lock.lock.unwrap;
while !*guard
// 通知线程:
let = &*pair;
*lock.lock.unwrap = true;
cvar.notify_one;
需要用 while 而非 if 检查条件——spurious wakeup 可能发生(操作系统可能在条件不满足时唤醒)。
Atomic 与 Ordering
use ;
static COUNTER: AtomicUsize = new;
COUNTER.fetch_add;
Relaxed: 只保证原子性,不保证与周围内存操作的顺序——适用: 单纯计数,不需要与其他变量同步 Acquire/Release: 单向同步——Acquire 保证后续读看到 Release 之前的写。适用: 锁实现 SeqCst: 最强——全局顺序一致。适用: 默认选择,除非你知道为什么要更弱
参考
- Rust Book: Chapter 16
- Rustonomicon: Atomics, memory ordering
- CppReference: memory_order (C++ 的定义也适用于 Rust 的原子模型)
Keywords: thread, Mutex, RwLock, mpsc, channel, Condvar, AtomicUsize, Ordering, SeqCst, Acquire, Release