I've been trying my best as a beginner to write a multi-threaded program then shutdown all threads gracefully without implementing Drop trait or just calling drop(T) or creating an expression that causes error intentionally. Code below is an implementation of what I wanted, it compiles and works fine but I don't have depth knowledge to detect any runtime problem
use std::{thread, time::{Duration, Instant}, sync::{Arc, Mutex, RwLock, mpsc}};
fn main() {
let (sender, receiver) = mpsc::channel::<String>();
let receiver = Arc::new(Mutex::new(receiver));
let signal_stop = Arc::new(RwLock::new(false));
let mut threads = Vec::with_capacity(6);
let signal_stop_ref_1 = Arc::clone(&signal_stop);
threads.push(thread::spawn(move || { // thread sending
let start_time = Instant::now();
loop {
let duration = start_time.elapsed().as_millis();
sender.send(format!("{duration} milliseconds")).unwrap();
if duration >= 30_000 {
let mut signal_stop = signal_stop_ref_1.write().unwrap();
*signal_stop = true;
break; // stop thread
}
thread::sleep(Duration::from_secs(1));
}
}));
for _ in 0..5 {
let (receiver, signal_stop_ref_2) = (
Arc::clone(&receiver),
Arc::clone(&signal_stop)
);
threads.push(thread::spawn(move || { // 5 threads receiving
loop {
let message = receiver.lock().unwrap().recv();
if *(signal_stop_ref_2.read().unwrap()) && message.is_err() {
break; // stop thread if conditions met
}
if let Ok(msg) = message {
println!("received after {}", msg);
}
}
}));
}
for thread in threads {
thread.join().unwrap();
}
println!("Flow back to main");
}