「读多写少就用 RwLock」是常见建议,但真实数据支持吗?这篇先验证 RwLock 的并行读优势,再验证 try 系列函数、同线程重复加锁的死锁,最后用极短临界区的微基准,看看 RwLock 什么时候反而更慢。
编译:成功
运行(退出码 0):
Mutex: 4 个线程各持锁 50 ms,总耗时约 210 ms(串行)
RwLock 读: 4 个线程各持读锁 50 ms,总耗时约 50 ms(并行)
RwLock 写: 4 个线程各持写锁 50 ms,总耗时约 220 ms(写锁互斥,串行)Mutex 的基础见Mutex<T> 与内部可变性。
编译:成功
运行(退出码 0):
持有写锁时:try_read = WouldBlock try_write = WouldBlock
持有读锁时:try_read = 成功 try_write = WouldBlock
Mutex 持有时:try_lock = WouldBlock
释放后:try_lock = 成功 编译:成功
运行(退出码 0):
拿到第一把锁
再等 300 ms:Err(Timeout)(同一线程第二次 lock 阻塞了)
主线程 try_lock: 拿不到,锁被卡住的线程占着 编译:成功
运行(退出码 0):
Mutex 4 线程 × 200 万次读: 149.6 ms
RwLock 4 线程 × 200 万次读: 917.4 ms
size_of::<Mutex<u64>>() = 24 size_of::<RwLock<u64>>() = 24 size_of::<u64>() = 8这是 macOS aarch64 上的一次微基准,其它平台与读写比例下结论可能不同;没有测混合读写。毒化的行为见catch_unwind。