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>> { 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());}
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());}
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 local_counter = Arc::clone(&counter); let handle = thread::spawn(move || { for _ in 0..increments { let mut num = local_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 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>> { Arc::new(Mutex::new(initial))}pub fn increment_counter( counter: Arc<Mutex<i32>>, threads: usize, increments: usize,) -> Vec<JoinHandle<()>> { let mut handlers = vec![]; for _ in 0..threads { let cloned = Arc::clone(&counter); let handler = thread::spawn(move || { for _ in 0..increments { let mut num = cloned.lock().unwrap(); *num += 1; } }); handlers.push(handler); } handlers}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 cloned = Arc::clone(&data); thread::spawn(move || { let mut cloned_data = cloned.lock().unwrap(); modifier(&mut cloned_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(); for _ in 0..increments { *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 || { 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 handles = vec![]; for _ in 0..threads { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut num = counter.lock().unwrap(); for _ in 0..increments { *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 || { 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::{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 ccounter = Arc::clone(&counter); spawn(move || { *ccounter.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 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 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<()> { thread::spawn(move || { let mut data_lock = data.lock().unwrap(); modifier(&mut data_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<()>> { 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<()> { 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 (0..threads) .map(|_| { let cloned = counter.clone(); thread::spawn(move || { let mut cnt = cloned.lock().unwrap(); *cnt += 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 cloned = data.clone(); thread::spawn(move || { modifier(&mut cloned.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<()>> { let mut handles = Vec::new(); for _ in 0..threads { let counter = Arc::clone(&counter); handles.push(thread::spawn(move || { for _ in 0..increments { dbg!(); *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 let mut v = Vec::new(); for _ in 0..threads { let c = counter.clone(); v.push(thread::spawn(move || { *c.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 thread::spawn(move || { let d = &mut data.lock().unwrap(); modifier(d); })}// 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 = Arc::clone(&counter); let handle = thread::spawn(move || { let mut data = counter.lock().unwrap(); *data += 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::new(); for _ in 0..threads { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { for _ in 0..increments { let mut data = counter.lock().unwrap(); *data += 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 || { 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::new(); for _ in 0..threads { let counter = Arc::clone(&counter); let handle = thread::spawn(move || { for _ in 0..increments { let mut data = counter.lock().unwrap(); *data += 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 || { 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 threads_joins_hanlders: Vec<JoinHandle<()>> = Vec::new(); for _ in 0..threads{ let counter_handler = Arc::clone(&counter); let generated_thread_handler = thread::spawn(move || { let mut guard = counter_handler.lock().unwrap(); *guard += increments as i32; }); threads_joins_hanlders.push(generated_thread_handler); } threads_joins_hanlders }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 thread_handler = thread::spawn(move || { let mut guard = data.lock().unwrap(); modifier(&mut guard); }); thread_handler }// 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 res: Vec<JoinHandle<()>> = vec![]; for _ in 0..threads { let counter_handle = Arc::clone(&counter); let handle = thread::spawn(move || { let mut counter_local = counter_handle.lock().unwrap(); *counter_local += increments as i32; }); res.push(handle); } 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 local_lock = data.lock().unwrap(); modifier(&mut local_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>> { // 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(|_| { Arc::clone(&counter) }) .map(|counter| thread::spawn(move || { let mut counter = counter.lock().unwrap(); *counter = *counter + 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 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::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::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 thread::spawn( move || { let mut inner_data = data.lock().unwrap(); modifier(&mut inner_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::new(); for _ in 0..threads { let counter = Arc::clone(&counter); handles.push(thread::spawn(move || { let mut data = counter.lock().unwrap(); *data += increments as i32; })) } handles}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { 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 (0..threads).into_iter() .map(|_| Arc::clone(&counter)) .map(|counter| { thread::spawn(move || { let mut data = counter.lock().unwrap(); *data += 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 = Arc::clone(&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 (0..threads).map(|_| { let counter = counter.clone(); thread::spawn(move || { let mut counter_guard = counter.lock().unwrap(); *counter_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 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 (0..threads) .map(|_| Arc::clone(&counter)) .map(|counter| thread::spawn(move || { let mut counter = counter.lock().unwrap(); *counter += 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 = 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 threads_buf = vec![]; for _ in 0..threads { let c = counter.clone(); let t = thread::spawn(move || { *c.lock().unwrap() += increments as i32; }); threads_buf.push(t); } threads_buf}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 = data.clone(); 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};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<JoinHandle<()>> = Vec::with_capacity(threads); for _ in 0..threads { let cloned =Arc::clone(&counter); let handle = thread::spawn(move || { let mut x = cloned.lock().unwrap(); *x += 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 let cloned = Arc::clone(&data); thread::spawn(move || { let mut data = cloned.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::DerefMut;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<JoinHandle<()>> = vec![]; for _ in 0..threads { let shared_counter = Arc::clone(&counter); let handle = thread::spawn(move || { let mut guard = shared_counter.lock().unwrap(); *guard += increments as i32; }); res.push(handle); } 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 || 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 counter=counter.clone(); thread::spawn(move || { let mut counter=counter.lock().unwrap(); *counter += 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>> { 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 || { *counter.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<()> { let data_copy = Arc::clone(&data); thread::spawn(move || { modifier(&mut *data_copy.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![]; for _ in 0..threads { let counter = Arc::clone(&counter); handles.push( thread::spawn(move || { let mut counter = counter.lock().unwrap(); *counter += increments as i32; }) ) } return handles;}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { thread::spawn(move || { let mut d = data.lock().unwrap(); modifier(&mut d); })}// 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 || { let mut counter = counter.lock().unwrap(); *counter += 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 = 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::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 spawned: Vec<JoinHandle<()>> = vec![]; for _ in 0..threads { let counter = Arc::clone(&counter); spawned.push(std::thread::spawn(move || { let mut counter = counter.lock().unwrap(); *counter += increments as i32; })); } spawned}pub fn modify_shared_data<T: Send + 'static>( data: Arc<Mutex<T>>, modifier: fn(&mut T),) -> JoinHandle<()> { std::thread::spawn(move || { let mut modify = data.lock().unwrap(); modifier(&mut modify); })}// 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 spawned_threads: Vec<JoinHandle<()>> = Vec::new(); for _ in 0..threads { // clone the Arc again here for each thread to resolve ownership issues let counter = Arc::clone(&counter); spawned_threads.push( thread::spawn(move || { // obtain the lock and unwrap let mut counter = counter.lock().unwrap(); // increment the counter by the given increments *counter += increments as i32; }) ); } spawned_threads}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());}