When safe mutable access to a shared resource is required, the access can be provided by the use of mutex. Mutex is a portmanteau for mutual exclusion, a widely used synchronization primitive for ensuring that a piece of code is executed by only one thread at a time. A mutex in general is a guard object which a thread acquires to protect data that is meant to be shared or modified by multiple threads. It works by prohibiting access to a value from more than one thread at a time by locking the value. If one of the threads has a lock on the mutex type, no other thread can run the same code until the thread that holds the lock is done with it.
The std::sync module from the standard library contains the Mutex type allowing one to mutate data from threads in thread-safe manner.
The following code example shows how to use the Mutex type from a single child thread:
// mutex_basics.rs
use std::sync::Mutex;
use std::thread;
fn main() {
let m = Mutex::new(0);
let c = thread::spawn(move || {
{
*m.lock().unwrap() += 1;
}
let updated = *m.lock().unwrap();
updated
});
let updated = c.join().unwrap();
println!("{:?}", updated);
}
Running this works as expected. But, this won't work when multiple threads try to access the value as Mutex doesn't provide shared mutability. To allow a value inside a Mutex to be mutated from multiple threads, we need to compose it it the Arc type. Let's see how to do that next.