One common challenge in concurrency is managing shared state across multiple threads. Rust's ownership model, along with types like Mutex
and Arc
(atomic reference counting), makes this task safe and efficient.
In this challenge, you will implement a generic shared state system and use it to create thread-safe counters and other shared data structures.
Implement three functions that demonstrate different aspects of shared state concurrency:
create_shared_data
: Creates shared state with any type T
increment_counter
: Demonstrates multiple threads modifying shared statemodify_shared_data
: Generic function for thread-safe modificationsThe create_shared_data
function should:
T
Mutex
and Arc
The increment_counter
function should:
Arc<Mutex<i32>>
The modify_shared_data
function should:
unwrap()
to simplify the codemain
function to see how the functions are usedArc::new(Mutex::new(initial))
to create thread-safe containersArc
when passing it to a new thread. e.g. let cloned = Arc::clone(&shared_data)
lock().unwrap()
to access the data inside the MutexSend
trait and have a lifetime that outlives the thread 'static
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads).map(|_| { let share_counter = counter.clone(); thread::spawn(move|| { let mut guard = share_counter.lock().unwrap(); *guard += increments as i32 }) }).collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data = data.clone(); thread::spawn(move || { let mut guard = data.lock().unwrap(); modifier(&mut guard); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads).map(|_| { let counters = Arc::clone(&counter); thread::spawn(move || { // necessary lock() as guard and unwrap to access interior Arc prevent poisioning let mut data_guard = counters.lock().unwrap(); *data_guard += increments as i32; }) }).collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let clone_data = Arc::clone(&data); thread::spawn(move || { modifier(&mut clone_data.lock().unwrap()) })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};use std::ops::DerefMut;pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new((Mutex::new(initial)))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = vec![]; for _ in 0..threads{ let c = Arc::clone(&counter); let h = thread::spawn( move || { for _ in 0..increments{ *c.lock().unwrap().deref_mut() += 1; } }); handles.push(h); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn( move||{ modifier( data.lock().unwrap().deref_mut()); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads).map(|_| { let arc_count = Arc::clone(&counter); thread::spawn(move||{ let mut c = arc_count.lock().unwrap(); *c += increments as i32; }) }).collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { let arc_data = Arc::clone(&data); thread::spawn(move ||{ let mut data = arc_data.lock().unwrap(); modifier(&mut data) })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads) .map(|_| { let counter = Arc::clone(&counter); thread::spawn(move || { let mut counter = counter.lock().unwrap(); *counter += i32::try_from(increments).unwrap(); }) }) .collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data = Arc::clone(&data); thread::spawn(move || { modifier(&mut data.lock().unwrap()); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::new(); for i in 0..threads { let counter = counter.clone(); handles.push(thread::spawn(move || { for i in 0..increments { *counter.lock().unwrap() += 1; } })); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || { modifier(&mut data.lock().unwrap()) })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads).map( |_| { let m = Arc::clone(&counter); thread::spawn( move || { let mut c = m.lock().unwrap(); *c += increments as i32; } ) } ).collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn( move || { let a = Arc::clone(&data); let data: &mut T = &mut a.lock().unwrap(); modifier(data); } )}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial)) // 1. Initialize and return a new Arc<Mutex<T>> with the initial value}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { (0..threads) .map(|_| { let counter = Arc::clone(&counter); thread::spawn(move || { let mut guard = counter.lock().unwrap(); *guard += increments as i32; }) }) .collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { thread::spawn(move || { let mut guard = data.lock().unwrap(); modifier(&mut guard); }) // 3. Use a new thread to modify the shared data}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::new(); for _ in 0..threads { let count = Arc::clone(&counter); let handle = thread::spawn( move || { let mut num = count.lock().unwrap(); *num += increments as i32; } ); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data_clone = Arc::clone(&data); let handle = thread::spawn( move || { let mut string_data = data_clone.lock().unwrap(); modifier(&mut string_data); } ); handle}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial)) // 1. Initialize and return a new Arc<Mutex<T>> with the initial value}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { (0..threads) .map(|_| { let counter = counter.clone(); std::thread::spawn(move || *counter.lock().expect("error") += increments as i32) }) .collect() // 2. Increment the counter by the given increments using the given number of threads}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { let handle = data.clone(); std::thread::spawn(move || modifier(&mut *handle.lock().expect("error on lock"))) // 3. Use a new thread to modify the shared data}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { let mut handles = Vec::with_capacity(threads); for _i in 0..threads { let data = Arc::clone(&counter); let r = thread::spawn(move || { *data.lock().unwrap() += increments as i32; }); handles.push(r); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { thread::spawn(move || { modifier(&mut data.lock().unwrap()) })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { (0..threads).map(|_| { let entry = Arc::clone(&counter); thread::spawn(move || { let mut entry = entry.lock().unwrap(); *entry += increments as i32; }) }).collect::<Vec<JoinHandle<()>>>()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { thread::spawn(move || { modifier(&mut data.lock().unwrap()) })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { (0..threads) .map(|_| { let counter_cloned = counter.clone(); thread::spawn(move || { *counter_cloned.lock().unwrap() += increments as i32; }) }) .collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { thread::spawn(move || { let mut data_ref = data.lock().unwrap(); modifier(&mut *data_ref); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new( Mutex::new(initial) )}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { (0..threads) .map(|_| { let counter = counter.clone(); thread::spawn(move || { for _ in 0..increments { let mut x = counter.lock().unwrap(); *x += 1 } }) }) .collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data = data.clone(); thread::spawn(move || { let mut x = data.lock().unwrap(); modifier(&mut *x); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{spawn, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads) .map(|_| { let counter = counter.clone(); spawn(move || { for _ in 0..increments { let mut x = counter.lock().expect("oops"); *x += 1; } }) }) .collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data = data.clone(); spawn(move || { let mut x = data.lock().expect("oops"); modifier(&mut *x); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};use std::ops::Deref;use std::ops::DerefMut;pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<Arc<Mutex<i32>>>> { // 2. Increment the counter by the given increments using the given number of threads let mut result = vec![]; for i in 0..threads { let cloned = counter.clone(); for j in 0..increments { *counter.lock().unwrap().deref_mut() += 1; } result.push(thread::spawn(move|| cloned)) } result}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move||modifier(&mut data.deref().lock().unwrap()))}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { (0..threads) .map(|_| { let counter = Arc::clone(&counter); thread::spawn(move || { for _ in 0..increments { let mut x = counter.lock().expect("oops"); *x += 1; } }) }) .collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { thread::spawn(move || { modifier(data.lock().as_mut().expect("oops")); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::new(); for _ in 0..threads { let counter_clone = Arc::clone(&counter); let handle = thread::spawn(move || { for _ in 0..increments { let mut num = counter_clone.lock().unwrap(); *num += 1; } }); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data //let data_clone = Arc::clone(&data); let handle = thread::spawn(move || { let mut data = data.lock().unwrap(); modifier(&mut data); }); handle}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::ops::DerefMut;use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { let mut thvec = vec![]; for _ in 0..threads { let local_counter = Arc::clone(&counter); thvec.push(thread::spawn(move || { for _ in 0..increments { *local_counter.lock().unwrap() += 1; } })); } thvec}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { thread::spawn(move || modifier(data.lock().unwrap().deref_mut()))}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{spawn, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles: Vec<JoinHandle<()>> = vec![]; for _i in 0..threads { let arc = Arc::clone(&counter); handles.push( spawn(move || { *arc.lock().unwrap() += increments as i32; }) ) } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let arc: Arc<Mutex<T>> = Arc::clone(&data); spawn(move || { let mut val = arc.lock().unwrap(); modifier(&mut val); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut res = vec![]; for i in 0..threads { let c = Arc::clone(&counter); res.push( thread::spawn( move || { for _ in 0..increments { let mut lock = c.lock().unwrap(); *lock += 1; } } ) ) } res}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || { let mut lock = data.lock().unwrap(); modifier(&mut *lock); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { (0..threads).map( |_| thread::spawn( { let counter = Arc::clone(&counter); move || { *counter.lock().unwrap() += increments as i32; } } ) ).collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { thread::spawn( move || { modifier(&mut data.lock().unwrap()); } )}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = vec![]; for _ in 0..threads { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { for _ in 0..increments { let mut num = counter.lock().unwrap(); *num += 1; } }); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data = Arc::clone(&data); thread::spawn(move || { let mut content = data.lock().unwrap(); modifier(&mut *content); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { (0..threads) .map(|_| counter.clone()) .map(|entry| thread::spawn(move || *entry.lock().unwrap() += increments as i32)) .collect::<Vec<JoinHandle<()>>>()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { let data_clone = data.clone(); thread::spawn(move || { let mut _data = data_clone.lock().unwrap(); modifier(&mut *_data); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { let mut handles = vec![]; for _ in 0..threads { let counter_clone = counter.clone(); let join_handle = thread::spawn(move || { let mut _counter = counter_clone.lock().unwrap(); *_counter += increments as i32 }); handles.push(join_handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { let data_clone = data.clone(); thread::spawn(move || { let mut _data = data_clone.lock().unwrap(); modifier(&mut *_data); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads).map(|_| counter.clone()).map(|counter_copy| thread::spawn(move || { let mut entry = counter_copy.lock().unwrap(); *entry += increments as i32; })).collect::<Vec<JoinHandle<()>>>()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data = Arc::clone(&data); thread::spawn(move || { let mut entry = data.lock().unwrap(); modifier(&mut entry); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::new(); for _ in 0..threads { let shared = Arc::clone(&counter); let handle = thread::spawn(move || { *shared.lock().unwrap() += increments as i32 }); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let shared = Arc::clone(&data); thread::spawn(move || { modifier(&mut shared.lock().unwrap()); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::with_capacity(threads); for _i in 0..threads { let data = Arc::clone(&counter); let r = thread::spawn(move || { *data.lock().unwrap() += increments as i32; }); handles.push(r); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data = data.clone(); thread::spawn(move || { modifier(&mut data.lock().unwrap()); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut v = Vec::with_capacity(threads); for _i in 0..threads { let data = Arc::clone(&counter); v.push(thread::spawn(move || { *data.lock().unwrap() += increments as i32; })); } v}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let d = Arc::clone(&data); thread::spawn(move || { modifier(&mut d.lock().unwrap()); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};use std::ops::DerefMut;pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial valuec return Arc::new(Mutex::new(initial));}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut res = Vec::with_capacity(threads); for _ in 0..threads{ let c = Arc::clone(&counter); res.push(thread::spawn(move || -> () { *c.lock().expect("poisioned") += increments as i32; })); } return res;}pub fn modify_shared_data<T>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> where T: Send + 'static,{ // 3. Use a new thread to modify the shared data let d = Arc::clone(&data); return thread::spawn(move || -> () { modifier(d.lock().expect("poisioned").deref_mut()); });}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = vec![]; for _ in 0..threads { let counter_arc = Arc::clone(&counter); let handle = thread::spawn( move || { *counter_arc.lock().unwrap() += increments as i32 } ); handles.push(handle) } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn( move || { let _ = modifier(&mut data.lock().unwrap()); } )}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = vec![]; for _ in 0..threads { let counter_arc = Arc::clone(&counter); let handle = thread::spawn( move || { *counter_arc.lock().unwrap() += increments as i32 } ); handles.push(handle) } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn( move || { let _ = modifier(&mut data.lock().unwrap()); } )}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { let mut handles = vec![]; for _ in 0..threads { let ar = Arc::clone(&counter); let handle = thread::spawn(move || { let mut data = ar.lock().unwrap(); *data += increments as i32; }); handles.push(handle); } return handles;}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { let arc = Arc::clone(&data); thread::spawn(move || { let mut data = arc.lock().unwrap(); modifier(&mut data); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut ret = Vec::new(); for _ in 0..threads { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut counter = counter.lock().unwrap(); *counter += increments as i32; }); ret.push(handle); } ret}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || { modifier(&mut *data.lock().unwrap()); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut vecs = Vec::with_capacity(threads); for i in 0..threads { let counter_clone = Arc::clone(&counter); vecs.push(thread::spawn(move || *counter_clone.lock().unwrap() += increments as i32)); } vecs}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || modifier(&mut data.lock().unwrap()))}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { let mut threads_vec = Vec::with_capacity(threads); let increments = increments as i32; for _ in 0..threads { let counter_clone = Arc::clone(&counter); threads_vec.push(thread::spawn(move || *counter_clone.lock().unwrap() += increments)); } threads_vec}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { thread::spawn(move || modifier(&mut data.lock().unwrap()))}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut vec = Vec::new(); for _ in 0..threads { let counter_clone = Arc::clone(&counter); vec.push(thread::spawn(move || { for _ in 0..increments { let mut num = counter_clone.lock().unwrap(); *num += 1; } })); } vec}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || { let mut locked_data = data.lock().unwrap(); modifier(&mut *locked_data); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = vec![]; for _ in 0..threads { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += increments as i32; }); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data = Arc::clone(&data); thread::spawn(move || { /*let mut binding = data.lock().unwrap(); let val = binding.deref_mut();*/ let mut val = data.lock().unwrap(); modifier(&mut val); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut result = vec![]; for _ in 0..threads { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); *num += increments as i32; }); result.push(handle); } result}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { let data = Arc::clone(&data); // 3. Use a new thread to modify the shared data thread::spawn(move || { let mut val = data.lock().unwrap(); modifier(&mut val); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads).into_iter().map(|_| { let counter = Arc::clone(&counter); std::thread::spawn( move || { let mut n = counter.lock().unwrap(); *n += increments as i32; }) } ).collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data std::thread::spawn(move || { modifier(&mut data.lock().unwrap()); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::with_capacity(threads); for _ in 0..threads { let counter_clone = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter_clone.lock().unwrap(); *num += increments as i32; }); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || modifier(&mut data.lock().unwrap()))}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads).map(|_| thread::spawn({let counter = Arc::clone(&counter); move || { *counter.lock().unwrap() += increments as i32; }})).collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || { modifier(&mut data.lock().unwrap()) })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::ops::AddAssign;use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads).map(|_| { let counter = counter.clone(); thread::spawn(move || { counter.lock().unwrap().add_assign(increments as i32); }) }).collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || { let data = data.clone(); modifier(&mut data.lock().unwrap()); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::new(); for _ in 0..threads { let counter_clone = Arc::clone(&counter); let handle = thread::spawn(move || { for _ in 0..increments { let mut num = counter_clone.lock().unwrap(); *num += 1; } }); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data let data_clone = Arc::clone(&data); thread::spawn(move || { let mut data = data_clone.lock().unwrap(); modifier(&mut data); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::ops::AddAssign;use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads (0..threads).map(|_| { let counter = counter.clone(); thread::spawn(move || { counter.lock().unwrap().add_assign(increments as i32); }) }).collect()}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || modifier(&mut data.lock().unwrap()))}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles: Vec<JoinHandle<()>> = Vec::new(); for _ in 0..threads { let clounter_clone: Arc<Mutex<i32>> = counter.clone(); let handle = thread::spawn(move || { let mut val = clounter_clone.lock().unwrap(); *val += increments as i32; }); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || { let mut data = data.lock().unwrap(); modifier(&mut data); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::with_capacity(threads); for _ in 0..threads { let counter_clone = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter_clone.lock().unwrap(); *num += increments as i32; }); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || modifier(&mut data.lock().unwrap()))}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::with_capacity(threads); for _ in 0..threads { let counter_clone = Arc::clone(&counter); let handle = thread::spawn(move || { for _ in 0..increments { let mut num = counter_clone.lock().unwrap(); *num += 1; } }); handles.push(handle); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || modifier(&mut data.lock().unwrap()))}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::new(); for i in 0..threads { let cntr = Arc::clone(&counter); handles.push( thread::spawn(move || { let mut num = cntr.lock().unwrap(); *num += increments as i32; }) ); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || { modifier(&mut data.lock().unwrap()) }) }// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}
use std::sync::{Arc, Mutex};use std::thread::{self, JoinHandle};pub fn create_shared_data<T>(initial: T) -> Arc<Mutex<T>> { // 1. Initialize and return a new Arc<Mutex<T>> with the initial value Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { // 2. Increment the counter by the given increments using the given number of threads let mut handles = Vec::with_capacity(threads); for _ in 0..threads { let counter = Arc::clone(&counter); handles.push(thread::spawn(move || { let mut num = counter.lock().unwrap(); for _ in 0..increments { *num += 1; } })); } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { // 3. Use a new thread to modify the shared data thread::spawn(move || { modifier(&mut data.lock().unwrap()); })}// Example usagepub fn main() { let counter = create_shared_data(0); let handles = increment_counter(Arc::clone(&counter), 5, 10); for handle in handles { handle.join().unwrap(); } println!("Counter value: {}", *counter.lock().unwrap()); let shared_string = create_shared_data(String::from("Hello")); let handle = modify_shared_data(shared_string.clone(), |s| s.push_str(" World")); handle.join().unwrap(); println!("Modified string: {}", *shared_string.lock().unwrap());}