use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use std::time::Duration;
structChopstick;
structPhilosopher {
name: String,
left_chopstick: Arc<Mutex<Chopstick>>,
right_chopstick: Arc<Mutex<Chopstick>>,
thoughts: mpsc::SyncSender<String>,
}
impl Philosopher {
fnthink(&self) {
self.thoughts
.send(format!("Eureka! {} has a new idea!", &self.name))
.unwrap();
}
fneat(&self) {
println!("{} is trying to eat", &self.name);
let _left = self.left_chopstick.lock().unwrap();
let _right = self.right_chopstick.lock().unwrap();
println!("{} is eating...", &self.name);
thread::sleep(Duration::from_millis(10));
}
}
static PHILOSOPHERS: &[&str] =
&["Socrates", "Hypatia", "Plato", "Aristotle", "Pythagoras"];
fnmain() {
let (tx, rx) = mpsc::sync_channel(10);
let chopsticks = PHILOSOPHERS
.iter()
.map(|_| Arc::new(Mutex::new(Chopstick)))
.collect::<Vec<_>>();
for i in0..chopsticks.len() {
let tx = tx.clone();
letmut left_chopstick = Arc::clone(&chopsticks[i]);
letmut right_chopstick =
Arc::clone(&chopsticks[(i + 1) % chopsticks.len()]);
// To avoid a deadlock, we have to break the symmetry// somewhere. This will swap the chopsticks without deinitializing// either of them.if i == chopsticks.len() - 1 {
std::mem::swap(&mut left_chopstick, &mut right_chopstick);
}
let philosopher = Philosopher {
name: PHILOSOPHERS[i].to_string(),
thoughts: tx,
left_chopstick,
right_chopstick,
};
thread::spawn(move || {
for _ in0..100 {
philosopher.eat();
philosopher.think();
}
});
}
drop(tx);
for thought in rx {
println!("{thought}");
}
}