1 个不稳定版本
使用旧的 Rust 2015
0.1.0 | 2018年4月28日 |
---|
#849 在 并发
50KB
650 行
灵活锁
本 crate 旨在提供泛型、灵活的锁定原语实现。目前,它仅提供 Mutex
类型(即没有 RwLock
等),没有 毒化,也没有 try_lock
。如果有兴趣,未来可以添加对这些的支持(欢迎补丁)。在 panic=abort 的情况下,不需要毒化。
提供的类型允许在布局和锁定实现方面具有灵活性。
与 std::sync::Mutex
的区别
- 无毒化。
- 无
try_lock
。 - 底层的原始互斥锁原语可以是任何类型,在
Box
中或不在其中,只要实现了RawMutex
trait。请谨慎选择。 - 原始互斥锁原语可以嵌入到数据类型的任何位置。请参阅
MutexWrap
类型,这是一个更类似于std::sync::Mutex
的变体,但仍允许使用特定的原始互斥锁原语。 - 谨慎使用,这可以允许通过 FFI 共享数据并竞争相同的锁。请参阅
ffi-example
目录。
示例
extern crate flexible_locks;
#[macro_use]
extern crate flexible_locks_derive;
use flexible_locks::{Mutex, RawMutex};
// Pick your choice of raw mutex;
#[cfg(windows)]
use flexible_locks::SRWLOCK as RawOsMutex;
#[cfg(unix)]
use flexible_locks::pthread_mutex_t as RawOsMutex;
use std::sync::Arc;
use std::thread;
use std::sync::mpsc::channel;
#[derive(MutexProtected, Default)]
struct Data {
a: usize,
b: usize,
#[mutex]
mutex: RawOsMutex,
}
const N: usize = 10;
fn main() {
// Spawn a few threads to increment a shared variable (non-atomically),
// and let the main thread know once all increments are done.
//
// Here we're using an Arc to share memory among threads, and the data
// inside the Arc is protected with a mutex.
let data = Arc::new(Mutex::new(Data::default()));
let (tx, rx) = channel();
for _ in 0..N {
let (data, tx) = (data.clone(), tx.clone());
thread::spawn(move || {
// The shared state can only be accessed once the lock is held.
// Our non-atomic increment is safe because we're the only thread
// which can access the shared state when the lock is held.
let mut data = data.lock();
data.a += 1;
if data.a == N {
tx.send(()).unwrap();
}
// the lock is unlocked here when `data` goes out of scope.
});
}
rx.recv().unwrap();
}
功能
可以启用 parking_lot
功能,为 parking_log::Mutex<()>
提供一个 RawMutex
实现。
许可证:Apache-2.0/MIT
依赖项
~2.5MB
~51K SLoC