Skip to main content

Rust 并发基础

本章主要讲:

  • Rust 如何创建线程
  • 线程相关的基础概念

读写锁​

由于 Mutex 只关注互斥的访问, 需要一种机制来保证可以让多个读者进入, 或只让一个写者进入, 这种情况就需要读写锁. Rust 标准库提供了 RwLock<T> 类型用于这样的场景.

RwLock 的 API 和 Mutex 有不同, 它提供了 read 和 write 两个方法分别用于读者和写者, 且分别获取到 RwLockReadGuard 和 RwLockWriteGuard. 前者只实现了 Deref, 后者实现了 DerefMut. 这样被保护的数据就可以分别用于只读和写, 可以将其视作 RefCell 的多线程版本.

RwLock<T> 需要 T 的类型是 Send 和 Sync 的, 即类型是可以安全地跨线程传递所有权.

Rust 标准库中的读写锁是和平台相关的, 且绝大部分实现都会在 writer wait 的时候阻塞新的 reader, 及时现在已经是 reader lock 的状态, 这样可以避免 writer 饥饿.

等待条件: 线程 Parking 和条件变量​

当数据被多个线程改变, 许多情况下需要这些线程等待某些事件以及某些数据条件变为 true. 比如通过 mutex 保护的 Vec, 我们希望等待它里面包含了数据后再进行处理. 如果我们只使用 Mutex, 则需要我们持续去检查 Vec 是否有数据然后再决定是否解锁.

Thread Parking​

thread parking 是让某个线程等待另外一个线程通知的机制. 某个线程可以 park 它自己, 让自己睡眠, 从而避免浪费 CPU 资源. 当条件允许时, 另外一个线程可以将这个休眠的线程唤醒(unpark).

在标准库中有 park 和 unpark 两个函数用于此目的.