1 个不稳定版本
使用旧的 Rust 2015
0.1.0 | 2018年6月7日 |
---|
#1088 在 并发
24KB
374 行
PairLock
适用于频繁读取和偶尔写入的场景的读写锁。
读取是无等待的,并且写入不会被后续的读取所阻塞。写入会相互阻塞。
这是通过存储两个 T
的值并标记其中一个为活动状态来实现的:读取者看到活动值,而写入者在切换活动状态之前会修改非活动的一个。
我不是无锁编程的专家,并且我只在 x86_64 上进行了测试,但是代码大量使用了 fence(SeqCst)
。
它可以与任何(大小)类型一起使用,但是将它们包裹在 Box
或 Arc
中可能会通过减少伪共享来提高性能。
没有中毒。
实现细节
PairLock
是一种不需要双字原子操作的差异引用计数的变体
一个 AtomicUsize
存储活动槽位的索引和该槽位启动的读取总数。一个特定槽位的 AtomicUsize
存储该槽位完成读取的总数。当前的读取计数是这些变量的差。只要当前读取数不超过 usize::MAX/2
,则回绕是可以接受的。非活动槽位的启动读取数存储在一个仅由写入者使用的互斥锁中。
读取通过增加第一个变量开始,通过增加第二个变量结束。写入通过锁定互斥锁并等待所有非活动槽位的读取完成开始,通过交换第一个变量的值与互斥锁中的值结束。
该算法类似于左右锁定,但更简单且效率不高:左右锁定通过具有多个计数器来减少共享,而读取者只需要修改其中一个。
许可证
根据您的选择,许可为以下之一
- Apache 许可证2.0版本,(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
。
贡献
除非您明确说明,否则根据 Apache-2.0 许可证定义的,您提交的任何旨在包含在工作中的有意贡献,应如上所述双重许可,无需任何附加条款或条件。