#[repr(align(128))]pub struct Mutex<T: ?Sized> {
raw: RawMutex,
value: UnsafeCell<T>,
}
Expand description
A high-level primitive that provides safe, mutable access to a shared resource.
Unlike more traditional mutexes, Mutex
can safely provide both shared, immutable access (via
read_lock()
) as well as exclusive, mutable access (via lock()
) to an underlying resource
with no loss of performance.
Poisoning
Mutex
does not support lock poisoning so if a thread panics while holding the lock, the
poisoned data will be accessible by other threads in your program. If you need to guarantee that
other threads cannot access poisoned data then you may wish to wrap this Mutex
inside another
type that provides the poisoning feature. See the implementation of std::sync::Mutex
for an
example of this.
Fairness
This Mutex
implementation does not guarantee that threads will acquire the lock in the same
order that they call lock()
or read_lock()
. However it will attempt to prevent long-term
starvation: if a thread repeatedly fails to acquire the lock beyond a threshold then all other
threads will fail to acquire the lock until the starved thread has acquired it.
Similarly, this Mutex
will attempt to balance reader and writer threads: once there is a
writer thread waiting to acquire the lock no new reader threads will be allowed to acquire it.
However, any reader threads that were already waiting will still be allowed to acquire it.
Examples
use std::sync::Arc;
use std::thread;
use std::sync::mpsc::channel;
use cros_async::{block_on, sync::Mutex};
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(Mutex::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 = block_on(data.lock());
*data += 1;
if *data == N {
tx.send(()).unwrap();
}
// the lock is unlocked here when `data` goes out of scope.
});
}
rx.recv().unwrap();
Fields
raw: RawMutex
value: UnsafeCell<T>
Implementations
sourceimpl<T> Mutex<T>
impl<T> Mutex<T>
sourcepub fn into_inner(self) -> T
pub fn into_inner(self) -> T
Consume the Mutex
and return the contained value. This method does not perform any locking
as the compiler will guarantee that there are no other references to self
and the caller
owns the Mutex
.
sourceimpl<T: ?Sized> Mutex<T>
impl<T: ?Sized> Mutex<T>
sourcepub async fn lock(&self) -> MutexGuard<'_, T>
pub async fn lock(&self) -> MutexGuard<'_, T>
Acquires exclusive, mutable access to the resource protected by the Mutex
, blocking the
current thread until it is able to do so. Upon returning, the current thread will be the
only thread with access to the resource. The Mutex
will be released when the returned
MutexGuard
is dropped.
Calling lock()
while holding a MutexGuard
or a MutexReadGuard
will cause a deadlock.
Callers that are not in an async context may wish to use the block_on
method to block the
thread until the Mutex
is acquired.
sourcepub async fn read_lock(&self) -> MutexReadGuard<'_, T>
pub async fn read_lock(&self) -> MutexReadGuard<'_, T>
Acquires shared, immutable access to the resource protected by the Mutex
, blocking the
current thread until it is able to do so. Upon returning there may be other threads that
also have immutable access to the resource but there will not be any threads that have
mutable access to the resource. When the returned MutexReadGuard
is dropped the thread
releases its access to the resource.
Calling read_lock()
while holding a MutexReadGuard
may deadlock. Calling read_lock()
while holding a MutexGuard
will deadlock.
Callers that are not in an async context may wish to use the block_on
method to block the
thread until the Mutex
is acquired.