pub type FairMutex<T> = Mutex<RawFairMutex, T>;Expand description
A mutual exclusion primitive that uses fair unlocking, useful for protecting shared data.
This mutex will block threads waiting for the lock to become available. The
mutex can be statically initialized or created by the new
constructor. Each mutex has a type parameter which represents the data that
it is protecting. The data can only be accessed through the RAII guards
returned from lock and try_lock, which guarantees that the data is only
ever accessed when the mutex is locked.
The regular mutex provided by parking_lot uses unfair unlocking by
default, whereas this mutex always uses a fair unlock. When there are parked
waiters, a fair unlock hands the mutex directly to one of them instead of
making the mutex available for the unlocking thread to immediately
re-acquire. Fair mutexes are generally slower, but can be useful when
predictable handoff is more important than throughput.
Fair unlocking does not imply strict first-in first-out ordering: threads
may acquire the mutex while spinning or through try_lock without joining
the queue of parked waiters.
§Differences from the standard library Mutex
- No poisoning, the lock is released normally on panic.
- Only requires 1 byte of lock state.
- Always uses fair unlocking.
- Supports locking with a timeout.
- Allows raw locking & unlocking without a guard.
§Examples
use parking_lot::FairMutex;
use std::sync::{Arc, mpsc::channel};
use std::thread;
const N: usize = 10;
// 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(FairMutex::new(0));
let (tx, rx) = channel();
for _ in 0..N {
let (data, tx) = (Arc::clone(&data), 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 += 1;
if *data == N {
tx.send(()).unwrap();
}
// the lock is unlocked here when `data` goes out of scope.
});
}
rx.recv().unwrap();Aliased Type§
pub struct FairMutex<T> { /* private fields */ }