From 45a807ac79dae1c56bee9c6fde28b93ed6a54d9c Mon Sep 17 00:00:00 2001 From: Frances Wingerter Date: Mon, 5 May 2025 18:26:42 +0000 Subject: [PATCH] concurrency: also show shared ownership when combining Arc/Mutex --- src/concurrency/shared-state/example.md | 38 ++++++++++++------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/src/concurrency/shared-state/example.md b/src/concurrency/shared-state/example.md index 180d9f94..419ea189 100644 --- a/src/concurrency/shared-state/example.md +++ b/src/concurrency/shared-state/example.md @@ -12,13 +12,15 @@ use std::thread; fn main() { let v = vec![10, 20, 30]; - let handle = thread::spawn(|| { - v.push(10); - }); - v.push(1000); + let mut handles = Vec::new(); + for i in 0..5 { + handles.push(thread::spawn(|| { + v.push(10 * i); + println!("v: {v:?}"); + })); + } - handle.join().unwrap(); - println!("v: {v:?}"); + handles.into_iter().for_each(|h| h.join().unwrap()); } ``` @@ -32,21 +34,17 @@ use std::thread; fn main() { let v = Arc::new(Mutex::new(vec![10, 20, 30])); - - let v2 = Arc::clone(&v); - let handle = thread::spawn(move || { - let mut v2 = v2.lock().unwrap(); - v2.push(10); - }); - - { - let mut v = v.lock().unwrap(); - v.push(1000); + 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:?}"); + })); } - handle.join().unwrap(); - - println!("v: {v:?}"); + handles.into_iter().for_each(|h| h.join().unwrap()); } ``` @@ -56,7 +54,7 @@ Notable parts: orthogonal. - Wrapping a `Mutex` in an `Arc` is a common pattern to share mutable state between threads. -- `v: Arc<_>` needs to be cloned as `v2` before it can be moved into another +- `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.