#lock #locking #shared-data #concurrent

nightly 自旋锁

基于自旋保护共享数据以进行并发访问的锁原语

1 个不稳定版本

使用旧的 Rust 2015

0.0.1 2015年3月9日

#34#shared-data

MIT 许可证

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