## Readers and writers
我们新的`TicketStore`工作正常,但读取性能不佳:由于 `Mutex` 无法区分readers和writers,因此同一时间只能有一个客户端读取特定的工单。
我们可以通过使用不同的锁定原语 `RwLock` 来解决这个问题。`RwLock` 代表读写锁。它允许多个读者同时访问数据,但同一时间只能有一个写者。
`RwLock` 提供了两种获取锁的方法:`read` 和 `write`。`read` 方法返回一个允许读取数据的守卫(guard)而 `write` 方法返回一个允许修改数据的守卫(guard)。
```rust
use std::sync::RwLock;
// 受读写锁保护的整数
let lock = RwLock::new(0);
// 获取 RwLock 的读取锁。
let guard1 = lock.read().unwrap();
// 获取第二个读锁
// 在第一个读锁仍然有效的情况下
let guard2 = lock.read().unwrap();
```
## 权衡取舍
表面上看,`RwLock` 似乎是个想都不用想的选择:它提供了 `Mutex` 功能的超集。既然可以用 `RwLock`,为什么还要用 `Mutex` 呢?
有两个关键原因:
- `RwLock` 比 `Mutex` 的开销更大。这是因为 `RwLock` 需要跟踪活跃的readers和writers的数量,而 `Mutex` 只需要跟踪锁是否被持有。如果读者多于writers,这种性能开销不是问题;但如果工作负载以写入为主,`Mutex` 可能是更好的选择。
- `RwLock` 可能会导致writers饥饿。如果始终有readers等待获取锁,writers可能永远没有机会执行操作。`RwLock` 不保证readers和writers获得锁的顺序。这取决于底层操作系统实现的策略,而这种策略可能对writers不公平。
对于现在我们做的例子来说,用 `RwLock` 就是一个很不错的选择,大多数的客户端都是读取ticket而不是修改ticket.