// threads3.rs // // Execute `rustlings hint threads3` or use the `hint` watch subcommand for a // hint. use std::sync::mpsc; use std::sync::Arc; use std::thread; use std::time::Duration; struct Queue { length: u32, first_half: Vec, second_half: Vec, } impl Queue { fn new() -> Self { Queue { length: 10, first_half: vec![1, 2, 3, 4, 5], second_half: vec![6, 7, 8, 9, 10], } } } fn send_tx(q: Queue, tx: mpsc::Sender) -> () { let qc = Arc::new(q); let qc1 = Arc::clone(&qc); let qc2 = Arc::clone(&qc); let tx1 = tx.clone(); thread::spawn(move || { for val in &qc1.first_half { println!("sending {:?}", val); tx1.send(*val).unwrap(); thread::sleep(Duration::from_secs(1)); } }); thread::spawn(move || { for val in &qc2.second_half { println!("sending {:?}", val); tx.send(*val).unwrap(); thread::sleep(Duration::from_secs(1)); } }); //In the given code, you have used the Arc (Atomic Reference Counting) to share ownership of the Queue struct between multiple threads. This allows you to have multiple producers by cloning the Arc reference. // By using Arc::clone(&qc), you create a new reference to the Arc that can be moved into a new thread. This ensures that each thread has its own reference to the shared Queue struct. // In this case, you have two threads, each with its own cloned reference to the Queue struct. Each thread then iterates over a different half of the queue and sends the values through the mpsc::Sender. // This way, you achieve multiple producers by sharing ownership of the Queue struct using Arc and cloning the reference for each thread. } #[test] fn main() { let (tx, rx) = mpsc::channel(); let queue = Queue::new(); let queue_length = queue.length; send_tx(queue, tx); let mut total_received: u32 = 0; for received in rx { println!("Got: {}", received); total_received += 1; } println!("total numbers received: {}", total_received); assert_eq!(total_received, queue_length) }