Skip to content

Instantly share code, notes, and snippets.

@ruiqurm
Last active December 28, 2022 06:17
Show Gist options
  • Save ruiqurm/82584a6c7e3117420515d989282e33d3 to your computer and use it in GitHub Desktop.
Save ruiqurm/82584a6c7e3117420515d989282e33d3 to your computer and use it in GitHub Desktop.
philosopher dining problem
use std::sync::mpsc;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
use rand::Rng;
struct Fork;
struct Philosopher {
name: String,
left_fork: Arc<Mutex<Fork>>,
right_fork: Arc<Mutex<Fork>>,
thoughts: mpsc::Sender<String>,
}
impl Philosopher {
fn think(&self) {
self.thoughts
.send(format!("Eureka! {} has a new idea!", &self.name))
.unwrap();
}
fn eat(&self) {
// Pick up forks...
loop{
let left_guard = self.left_fork.lock().unwrap();
if let Ok(ref mut mutex) = self.right_fork.try_lock(){
println!("{} is eating...", &self.name);
thread::sleep(Duration::from_millis(10));
return;
}
drop(left_guard);
thread::sleep(Duration::from_millis(rand::thread_rng().gen_range(10..100)));
}
}
}
static PHILOSOPHERS: &[&str] =
&["Socrates", "Plato", "Aristotle", "Thales", "Pythagoras"];
fn main() {
// Create forks
let forks = (0..PHILOSOPHERS.len()).map(|_| Arc::new(Mutex::new(Fork))).collect::<Vec<_>>();
let (tx, rx) = mpsc::channel();
// Create philosophers
let philosophers = PHILOSOPHERS.iter().enumerate().map(|(idx,name)|{
Philosopher{
name : name.to_string(),
left_fork : forks[idx].clone(),
right_fork : forks[(idx+1)%PHILOSOPHERS.len()].clone(),
thoughts : tx.clone(),
}
});
// Make them think and eat
for philosopher in philosophers{
thread::spawn(move||{
loop{
philosopher.eat();
philosopher.think();
}
});
}
// Output their thoughts
loop{
println!("{}", rx.recv().unwrap());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment