[][src]Struct tokio::sync::Mutex

pub struct Mutex<T> { /* fields omitted */ }
This is supported on feature="sync" only.

An asynchronous Mutex-like type.

This type acts similarly to an asynchronous std::sync::Mutex, with one major difference: lock does not block. Another difference is that the lock guard can be held across await points.

There are some situations where you should prefer the mutex from the standard library. Generally this is the case if:

  1. The lock does not need to be held across await points.
  2. The duration of any single lock is near-instant.

On the other hand, the Tokio mutex is for the situation where the lock needs to be held for longer periods of time, or across await points.

Examples:

use tokio::sync::Mutex;
use std::sync::Arc;

#[tokio::main]
async fn main() {
    let data1 = Arc::new(Mutex::new(0));
    let data2 = Arc::clone(&data1);

    tokio::spawn(async move {
        let mut lock = data2.lock().await;
        *lock += 1;
    });

    let mut lock = data1.lock().await;
    *lock += 1;
}
use tokio::sync::Mutex;
use std::sync::Arc;

#[tokio::main]
async fn main() {
    let count = Arc::new(Mutex::new(0));

    for _ in 0..5 {
        let my_count = Arc::clone(&count);
        tokio::spawn(async move {
            for _ in 0..10 {
                let mut lock = my_count.lock().await;
                *lock += 1;
                println!("{}", lock);
            }
        });
    }

    loop {
        if *count.lock().await >= 50 {
            break;
        }
    }
    println!("Count hit 50.");
}

There are a few things of note here to pay attention to in this example.

  1. The mutex is wrapped in an Arc to allow it to be shared across threads.
  2. Each spawned task obtains a lock and releases it on every iteration.
  3. Mutation of the data protected by the Mutex is done by de-referencing the obtained lock as seen on lines 12 and 19.

Tokio's Mutex works in a simple FIFO (first in, first out) style where all calls to lock complete in the order they were performed. In that way the Mutex is "fair" and predictable in how it distributes the locks to inner data. This is why the output of the program above is an in-order count to 50. Locks are released and reacquired after every iteration, so basically, each thread goes to the back of the line after it increments the value once. Finally, since there is only a single valid lock at any given time, there is no possibility of a race condition when mutating the inner value.

Note that in contrast to std::sync::Mutex, this implementation does not poison the mutex when a thread holding the MutexGuard panics. In such a case, the mutex will be unlocked. If the panic is caught, this might leave the data protected by the mutex in an inconsistent state.

Methods

impl<T> Mutex<T>[src]

pub fn new(t: T) -> Self[src]

This is supported on feature="sync" only.

Creates a new lock in an unlocked state ready for use.

Examples

use tokio::sync::Mutex;

let lock = Mutex::new(5);

pub async fn lock<'_, '_>(&'_ self) -> MutexGuard<'_, T>[src]

This is supported on feature="sync" only.

Locks this mutex, causing the current task to yield until the lock has been acquired. When the lock has been acquired, function returns a MutexGuard.

Examples

use tokio::sync::Mutex;

#[tokio::main]
async fn main() {
    let mutex = Mutex::new(1);

    let mut n = mutex.lock().await;
    *n = 2;
}

pub fn try_lock(&self) -> Result<MutexGuard<T>, TryLockError>[src]

This is supported on feature="sync" only.

Attempts to acquire the lock, and returns TryLockError if the lock is currently held somewhere else.

Examples

use tokio::sync::Mutex;

let mutex = Mutex::new(1);

let n = mutex.try_lock()?;
assert_eq!(*n, 1);

pub fn into_inner(self) -> T[src]

This is supported on feature="sync" only.

Consumes the mutex, returning the underlying data.

Examples

use tokio::sync::Mutex;

#[tokio::main]
async fn main() {
    let mutex = Mutex::new(1);

    let n = mutex.into_inner();
    assert_eq!(n, 1);
}

Trait Implementations

impl<T: Debug> Debug for Mutex<T>[src]

impl<T> Default for Mutex<T> where
    T: Default
[src]

impl<T> From<T> for Mutex<T>[src]

impl<T> Send for Mutex<T> where
    T: Send
[src]

impl<T> Sync for Mutex<T> where
    T: Send
[src]

Auto Trait Implementations

impl<T> !RefUnwindSafe for Mutex<T>

impl<T> Unpin for Mutex<T> where
    T: Unpin

impl<T> !UnwindSafe for Mutex<T>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> From<!> for T[src]

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.