mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-05-16 23:55:42 +02:00
63 lines
1.3 KiB
Markdown
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>
|