1 个不稳定版本
使用旧的 Rust 2015
0.0.1 | 2015年3月9日 |
---|
#34 在 #shared-data
19KB
350 行
spinlock-rs
Rust 中的自旋锁实现
构建
运行 cargo build
用法
该库实现了一个读写锁。当锁定自旋锁进行共享读访问时,您将获得受保护数据的引用,而当锁定进行独占写访问时,您将获得可变引用。
extern crate spinlock;
use spinlock::SpinLock;
fn main() {
let spin = SpinLock::new(0);
// Write access
{
let mut data = spin.write().unwrap();
*data += 1;
}
// Read access
{
let data = spin.read().unwrap();
println!("{}", *data);
}
}
请注意,自旋锁不会自己处理引用计数。您可能想要使用 Arc<SpinLock<T>>
在线程之间共享锁。
致谢
该实现借鉴了 Matt Dillon 为 DragonFlyBSD 编写的自旋锁实现。
lib.rs
:
一个读写自旋锁实现。自旋锁是一种特殊的锁,当它尝试获取已被另一个线程或代码路径持有的锁时,不会使线程休眠。相反,线程会在锁上 自旋,这意味着它将循环尝试再次获取它。
超时
此实现具有超时功能。自旋锁速度快,但应仅用于保护短的临界区,并且锁持有者应只持有锁很短的时间,以避免浪费 CPU 周期。如果线程尝试获取锁超过 MAX_WAIT
纳秒,它将引发恐慌。
乐观实现
该实现是乐观的。获取代码路径假定锁操作将成功,并且不会尝试最小化初始获取操作的成本。如果访问被竞争,实现将尝试最小化对 CPU 缓存的压力,直到它实际上可以获取锁。在 SPIN_COUNT
次重试之后,获取路径将在每次重试之间调用 thread::yield_now()
以允许其他线程运行并释放锁。
优先考虑独占访问
如果线程在竞争的独占访问尝试中自旋,则不会授予新的共享访问权限。这是为了防止读者 DOS 写入者。
毒化
如果一个独占持有者在持有锁的同时发生恐慌,可能会破坏一致性规则。实际上,受保护的数据可能处于不应该的状态。为了防止这种情况,如果一个独占持有者发生恐慌,锁将被毒化,将不会授予任何其他对锁的访问权限。
依赖项
~740KB
~13K SLoC