Example
Let us see Arc and Mutex in action:
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
use std::thread;
// use std::sync::{Arc, Mutex};
fn main() {
let v = vec![10, 20, 30];
let mut handles = Vec::new();
for i in 0..5 {
handles.push(thread::spawn(|| {
v.push(10 * i);
println!("v: {v:?}");
}));
}
handles.into_iter().for_each(|h| h.join().unwrap());
}
This slide should take about 8 minutes.
Possible solution:
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
use std::sync::{Arc, Mutex};
use std::thread;
fn main() {
let v = Arc::new(Mutex::new(vec![10, 20, 30]));
let mut handles = Vec::new();
for i in 0..5 {
let v = Arc::clone(&v);
handles.push(thread::spawn(move || {
let mut v = v.lock().unwrap();
v.push(10 * i);
println!("v: {v:?}");
}));
}
handles.into_iter().for_each(|h| h.join().unwrap());
}
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 to make a new reference for each new spawned thread. Notemovewas added to the lambda signature.- Blocks are introduced to narrow the scope of the
LockGuardas much as possible.