1
0
mirror of https://github.com/google/comprehensive-rust.git synced 2025-05-16 23:55:42 +02:00

63 lines
1.3 KiB
Markdown

---
minutes: 8
---
# Example
Let us see `Arc` and `Mutex` in action:
```rust,editable,compile_fail
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());
}
```
<details>
Possible solution:
```rust,editable
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:
- `v` is wrapped in both `Arc` and `Mutex`, because their concerns are
orthogonal.
- Wrapping a `Mutex` in an `Arc` is a common pattern to share mutable state
between threads.
- `v: Arc<_>` needs to be cloned to make a new reference for each new spawned
thread. Note `move` was added to the lambda signature.
- Blocks are introduced to narrow the scope of the `LockGuard` as much as
possible.
</details>