pub struct Mutex<T>where
T: ?Sized,{ /* private fields */ }
nonpoison_mutex
)Expand description
A mutual exclusion primitive useful for protecting shared data that does not keep track of lock poisoning.
For more information about mutexes, check out the documentation for the poisoning variant of
this lock at poison::Mutex
.
§Examples
Note that this Mutex
does not propagate threads that panic while holding the lock via
poisoning. If you need this functionality, see poison::Mutex
.
#![feature(nonpoison_mutex)]
use std::thread;
use std::sync::{Arc, nonpoison::Mutex};
let mutex = Arc::new(Mutex::new(0u32));
let mut handles = Vec::new();
for n in 0..10 {
let m = Arc::clone(&mutex);
let handle = thread::spawn(move || {
let mut guard = m.lock();
*guard += 1;
panic!("panic from thread {n} {guard}")
});
handles.push(handle);
}
for h in handles {
let _ = h.join();
}
println!("Finished, locked {} times", mutex.lock());
Implementations§
Source§impl<T> Mutex<T>
impl<T> Mutex<T>
Sourcepub const fn new(t: T) -> Mutex<T>
🔬This is a nightly-only experimental API. (nonpoison_mutex
)
pub const fn new(t: T) -> Mutex<T>
nonpoison_mutex
)Creates a new mutex in an unlocked state ready for use.
§Examples
#![feature(nonpoison_mutex)]
use std::sync::nonpoison::Mutex;
let mutex = Mutex::new(0);
Sourcepub fn get_cloned(&self) -> Twhere
T: Clone,
🔬This is a nightly-only experimental API. (lock_value_accessors
)
pub fn get_cloned(&self) -> Twhere
T: Clone,
lock_value_accessors
)Returns the contained value by cloning it.
§Examples
#![feature(nonpoison_mutex)]
#![feature(lock_value_accessors)]
use std::sync::nonpoison::Mutex;
let mut mutex = Mutex::new(7);
assert_eq!(mutex.get_cloned(), 7);
Sourcepub fn set(&self, value: T)
🔬This is a nightly-only experimental API. (lock_value_accessors
)
pub fn set(&self, value: T)
lock_value_accessors
)Sets the contained value.
§Examples
#![feature(nonpoison_mutex)]
#![feature(lock_value_accessors)]
use std::sync::nonpoison::Mutex;
let mut mutex = Mutex::new(7);
assert_eq!(mutex.get_cloned(), 7);
mutex.set(11);
assert_eq!(mutex.get_cloned(), 11);
Sourcepub fn replace(&self, value: T) -> T
🔬This is a nightly-only experimental API. (lock_value_accessors
)
pub fn replace(&self, value: T) -> T
lock_value_accessors
)Replaces the contained value with value
, and returns the old contained value.
§Examples
#![feature(nonpoison_mutex)]
#![feature(lock_value_accessors)]
use std::sync::nonpoison::Mutex;
let mut mutex = Mutex::new(7);
assert_eq!(mutex.replace(11), 7);
assert_eq!(mutex.get_cloned(), 11);
Source§impl<T> Mutex<T>where
T: ?Sized,
impl<T> Mutex<T>where
T: ?Sized,
Sourcepub fn lock(&self) -> MutexGuard<'_, T>
🔬This is a nightly-only experimental API. (nonpoison_mutex
)
pub fn lock(&self) -> MutexGuard<'_, T>
nonpoison_mutex
)Acquires a mutex, blocking the current thread until it is able to do so.
This function will block the local thread until it is available to acquire the mutex. Upon returning, the thread is the only thread with the lock held. An RAII guard is returned to allow scoped unlock of the lock. When the guard goes out of scope, the mutex will be unlocked.
The exact behavior on locking a mutex in the thread which already holds the lock is left unspecified. However, this function will not return on the second call (it might panic or deadlock, for example).
§Panics
This function might panic when called if the lock is already held by the current thread.
§Examples
#![feature(nonpoison_mutex)]
use std::sync::{Arc, nonpoison::Mutex};
use std::thread;
let mutex = Arc::new(Mutex::new(0));
let c_mutex = Arc::clone(&mutex);
thread::spawn(move || {
*c_mutex.lock() = 10;
}).join().expect("thread::spawn failed");
assert_eq!(*mutex.lock(), 10);
Sourcepub fn try_lock(&self) -> Result<MutexGuard<'_, T>, WouldBlock>
🔬This is a nightly-only experimental API. (nonpoison_mutex
)
pub fn try_lock(&self) -> Result<MutexGuard<'_, T>, WouldBlock>
nonpoison_mutex
)Attempts to acquire this lock.
This function does not block. If the lock could not be acquired at this time, then
WouldBlock
is returned. Otherwise, an RAII guard is returned.
The lock will be unlocked when the guard is dropped.
§Errors
If the mutex could not be acquired because it is already locked, then this call will return
the WouldBlock
error.
§Examples
use std::sync::{Arc, Mutex};
use std::thread;
let mutex = Arc::new(Mutex::new(0));
let c_mutex = Arc::clone(&mutex);
thread::spawn(move || {
let mut lock = c_mutex.try_lock();
if let Ok(ref mut mutex) = lock {
**mutex = 10;
} else {
println!("try_lock failed");
}
}).join().expect("thread::spawn failed");
assert_eq!(*mutex.lock().unwrap(), 10);
Sourcepub fn into_inner(self) -> T
🔬This is a nightly-only experimental API. (nonpoison_mutex
)
pub fn into_inner(self) -> T
nonpoison_mutex
)Consumes this mutex, returning the underlying data.
§Examples
#![feature(nonpoison_mutex)]
use std::sync::nonpoison::Mutex;
let mutex = Mutex::new(0);
assert_eq!(mutex.into_inner(), 0);
Sourcepub fn get_mut(&mut self) -> &mut T
🔬This is a nightly-only experimental API. (nonpoison_mutex
)
pub fn get_mut(&mut self) -> &mut T
nonpoison_mutex
)Returns a mutable reference to the underlying data.
Since this call borrows the Mutex
mutably, no actual locking needs to
take place – the mutable borrow statically guarantees no locks exist.
§Examples
#![feature(nonpoison_mutex)]
use std::sync::nonpoison::Mutex;
let mut mutex = Mutex::new(0);
*mutex.get_mut() = 10;
assert_eq!(*mutex.lock(), 10);
Sourcepub fn data_ptr(&self) -> *mut T
🔬This is a nightly-only experimental API. (mutex_data_ptr
)
pub fn data_ptr(&self) -> *mut T
mutex_data_ptr
)Returns a raw pointer to the underlying data.
The returned pointer is always non-null and properly aligned, but it is the user’s responsibility to ensure that any reads and writes through it are properly synchronized to avoid data races, and that it is not read or written through after the mutex is dropped.
Trait Implementations§
Source§impl<T> From<T> for Mutex<T>
impl<T> From<T> for Mutex<T>
Source§fn from(t: T) -> Mutex<T>
fn from(t: T) -> Mutex<T>
Creates a new mutex in an unlocked state ready for use.
This is equivalent to Mutex::new
.
impl<T> Send for Mutex<T>
T
must be Send
for a Mutex
to be Send
because it is possible to acquire
the owned T
from the Mutex
via into_inner
.
impl<T> Sync for Mutex<T>
T
must be Send
for Mutex
to be Sync
.
This ensures that the protected data can be accessed safely from multiple threads
without causing data races or other unsafe behavior.
Mutex<T>
provides mutable access to T
to one thread at a time. However, it’s essential
for T
to be Send
because it’s not safe for non-Send
structures to be accessed in
this manner. For instance, consider Rc
, a non-atomic reference counted smart pointer,
which is not Send
. With Rc
, we can have multiple copies pointing to the same heap
allocation with a non-atomic reference count. If we were to use Mutex<Rc<_>>
, it would
only protect one instance of Rc
from shared access, leaving other copies vulnerable
to potential data races.
Also note that it is not necessary for T
to be Sync
as &T
is only made available
to one thread at a time if T
is not Sync
.
Auto Trait Implementations§
impl<T> !Freeze for Mutex<T>
impl<T> !RefUnwindSafe for Mutex<T>
impl<T> Unpin for Mutex<T>
impl<T> UnwindSafe for Mutex<T>where
T: UnwindSafe + ?Sized,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self
to use its Binary
implementation when Debug
-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self
to use its Display
implementation when
Debug
-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self
to use its LowerExp
implementation when
Debug
-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self
to use its LowerHex
implementation when
Debug
-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self
to use its Octal
implementation when Debug
-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self
to use its Pointer
implementation when
Debug
-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self
to use its UpperExp
implementation when
Debug
-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self
to use its UpperHex
implementation when
Debug
-formatted.Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self
and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self
, then passes self.as_ref()
into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self
, then passes self.as_mut()
into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self
, then passes self.deref()
into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B>
of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B>
of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R>
view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R>
view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target
of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap()
only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow()
only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref()
only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut()
only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref()
only in debug builds, and is erased in release
builds.