diff --git a/exercises/threads/threads1.rs b/exercises/threads/threads1.rs index d6376db2..6110d9e2 100644 --- a/exercises/threads/threads1.rs +++ b/exercises/threads/threads1.rs @@ -6,8 +6,6 @@ // The program should wait until all the spawned threads have finished and // should collect their return values into a vector. -// I AM NOT DONE - use std::thread; use std::time::{Duration, Instant}; @@ -24,13 +22,13 @@ fn main() { let mut results: Vec = vec![]; for handle in handles { - // TODO: a struct is returned from thread::spawn, can you use it? + results.push(handle.join().unwrap()); } if results.len() != 10 { panic!("Oh no! All the spawned threads did not finish!"); } - + println!(); for (i, result) in results.into_iter().enumerate() { println!("thread {} took {}ms", i, result); diff --git a/exercises/threads/threads2.rs b/exercises/threads/threads2.rs index ada3d14a..8889dd70 100644 --- a/exercises/threads/threads2.rs +++ b/exercises/threads/threads2.rs @@ -3,25 +3,27 @@ // Building on the last exercise, we want all of the threads to complete their work but this time // the spawned threads need to be in charge of updating a shared value: JobStatus.jobs_completed -// I AM NOT DONE - -use std::sync::Arc; +use std::sync::{Arc, Mutex}; use std::thread; use std::time::Duration; +#[derive(Debug)] struct JobStatus { jobs_completed: u32, } fn main() { - let status = Arc::new(JobStatus { jobs_completed: 0 }); + let status = Arc::new(Mutex::new(JobStatus { jobs_completed: 0 })); let mut handles = vec![]; for _ in 0..10 { let status_shared = Arc::clone(&status); let handle = thread::spawn(move || { thread::sleep(Duration::from_millis(250)); // TODO: You must take an action before you update a shared value - status_shared.jobs_completed += 1; + match status_shared.lock() { + Err(e) => todo!(), + Ok(mut status) => status.jobs_completed += 1, + } }); handles.push(handle); } @@ -29,6 +31,7 @@ fn main() { handle.join().unwrap(); // TODO: Print the value of the JobStatus.jobs_completed. Did you notice anything // interesting in the output? Do you have to 'join' on all the handles? - println!("jobs completed {}", ???); + let status_shared = Arc::clone(&status); + println!("jobs completed {:?}", status_shared.lock().unwrap()) } } diff --git a/exercises/threads/threads3.rs b/exercises/threads/threads3.rs index 9e9f285a..7cb90f93 100644 --- a/exercises/threads/threads3.rs +++ b/exercises/threads/threads3.rs @@ -1,8 +1,6 @@ // threads3.rs // Execute `rustlings hint threads3` or use the `hint` watch subcommand for a hint. -// I AM NOT DONE - use std::sync::mpsc; use std::sync::Arc; use std::thread; @@ -26,13 +24,15 @@ impl Queue { fn send_tx(q: Queue, tx: mpsc::Sender) -> () { let qc = Arc::new(q); - let qc1 = Arc::clone(&qc); - let qc2 = Arc::clone(&qc); + let qc1 = qc.clone(); + let qc2 = qc.clone(); + let tx1 = tx.clone(); + let tx2 = tx.clone(); thread::spawn(move || { for val in &qc1.first_half { println!("sending {:?}", val); - tx.send(*val).unwrap(); + tx2.send(*val).unwrap(); thread::sleep(Duration::from_secs(1)); } }); @@ -40,7 +40,7 @@ fn send_tx(q: Queue, tx: mpsc::Sender) -> () { thread::spawn(move || { for val in &qc2.second_half { println!("sending {:?}", val); - tx.send(*val).unwrap(); + tx1.send(*val).unwrap(); thread::sleep(Duration::from_secs(1)); } });