Example
Let us see Arc and Mutex in action:
use std::thread;// use std::sync::{Arc, Mutex};fn main() {let mut v = vec![10, 20, 30];let handle = thread::spawn(|| {v.push(10);});v.push(1000);handle.join().unwrap();println!("v: {v:?}");}
Speaker Notes
Possible solution:
use std::sync::{Arc, Mutex};use std::thread;fn main() {let v = Arc::new(Mutex::new(vec![10, 20, 30]));let v2 = v.clone();let handle = thread::spawn(move || {let mut v2 = v2.lock().unwrap();v2.push(10);});{let mut v = v.lock().unwrap();v.push(1000);}handle.join().unwrap();{let v = v.lock().unwrap();println!("v: {v:?}");}}
Notable parts:
vis wrapped in bothArcandMutex, because their concerns are orthogonal.- Wrapping a
Mutexin anArcis a common pattern to share mutable state between threads.
- Wrapping a
v: Arc<_>needs to be cloned asv2before it can be moved into another thread. Notemovewas added to the lambda signature.- Blocks are introduced to narrow the scope of the
LockGuardas much as possible. - We still need to acquire the
Mutexto print ourVec.
Below is code to slowdown the main thread to invert the pushes into the vector.
use std::sync::{Arc, Mutex};use std::thread;use std::time::Duration;fn main() {let v = Arc::new(Mutex::new(vec![10, 20, 30]));let v2 = v.clone();let handle = thread::spawn(move || {let mut v2 = v2.lock().unwrap();v2.push(10);});thread::sleep(Duration::from_millis(10));{let mut v = v.lock().unwrap();v.push(1000);}handle.join().unwrap();{let v = v.lock().unwrap();println!("v: {v:?}");}}