Add block-based mutex unlocking example
This commit is contained in:
parent
4a04d086ca
commit
db5dfd2373
1 changed files with 17 additions and 7 deletions
|
@ -107,8 +107,8 @@ use crate::sys::locks as sys;
|
||||||
/// *guard += 1;
|
/// *guard += 1;
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// It is sometimes necessary to manually drop the mutex guard to unlock it
|
/// It is sometimes necessary to manually drop the mutex guard or to create an inner scope
|
||||||
/// sooner than the end of the enclosing scope.
|
/// to unlock it sooner than the end of the enclosing scope.
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use std::sync::{Arc, Mutex};
|
/// use std::sync::{Arc, Mutex};
|
||||||
|
@ -125,11 +125,18 @@ use crate::sys::locks as sys;
|
||||||
/// let res_mutex_clone = Arc::clone(&res_mutex);
|
/// let res_mutex_clone = Arc::clone(&res_mutex);
|
||||||
///
|
///
|
||||||
/// threads.push(thread::spawn(move || {
|
/// threads.push(thread::spawn(move || {
|
||||||
/// let mut data = data_mutex_clone.lock().unwrap();
|
/// // Here we use a block to limit the lifetime of the lock guard.
|
||||||
/// // This is the result of some important and long-ish work.
|
/// let result = {
|
||||||
/// let result = data.iter().fold(0, |acc, x| acc + x * 2);
|
/// let mut data = data_mutex_clone.lock().unwrap();
|
||||||
/// data.push(result);
|
/// // This is the result of some important and long-ish work.
|
||||||
/// drop(data);
|
/// let result = data.iter().fold(0, |acc, x| acc + x * 2);
|
||||||
|
/// data.push(result);
|
||||||
|
/// result
|
||||||
|
/// // The mutex guard gets dropped here, together with any other values
|
||||||
|
/// // created in the critical section.
|
||||||
|
/// };
|
||||||
|
/// // The guard created here is a temporary dropped at the end of the statement, i.e.
|
||||||
|
/// // the lock would not remain being held even if the thread did some additional work.
|
||||||
/// *res_mutex_clone.lock().unwrap() += result;
|
/// *res_mutex_clone.lock().unwrap() += result;
|
||||||
/// }));
|
/// }));
|
||||||
/// });
|
/// });
|
||||||
|
@ -146,6 +153,8 @@ use crate::sys::locks as sys;
|
||||||
/// // It's even more important here than in the threads because we `.join` the
|
/// // It's even more important here than in the threads because we `.join` the
|
||||||
/// // threads after that. If we had not dropped the mutex guard, a thread could
|
/// // threads after that. If we had not dropped the mutex guard, a thread could
|
||||||
/// // be waiting forever for it, causing a deadlock.
|
/// // be waiting forever for it, causing a deadlock.
|
||||||
|
/// // As in the threads a block could have been used instead of calling the
|
||||||
|
/// // `drop` function.
|
||||||
/// drop(data);
|
/// drop(data);
|
||||||
/// // Here the mutex guard is not assigned to a variable and so, even if the
|
/// // Here the mutex guard is not assigned to a variable and so, even if the
|
||||||
/// // scope does not end after this line, the mutex is still released: there is
|
/// // scope does not end after this line, the mutex is still released: there is
|
||||||
|
@ -160,6 +169,7 @@ use crate::sys::locks as sys;
|
||||||
///
|
///
|
||||||
/// assert_eq!(*res_mutex.lock().unwrap(), 800);
|
/// assert_eq!(*res_mutex.lock().unwrap(), 800);
|
||||||
/// ```
|
/// ```
|
||||||
|
///
|
||||||
#[stable(feature = "rust1", since = "1.0.0")]
|
#[stable(feature = "rust1", since = "1.0.0")]
|
||||||
#[cfg_attr(not(test), rustc_diagnostic_item = "Mutex")]
|
#[cfg_attr(not(test), rustc_diagnostic_item = "Mutex")]
|
||||||
pub struct Mutex<T: ?Sized> {
|
pub struct Mutex<T: ?Sized> {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue