Dining Philosophers

The dining philosophers problem is a classic problem in concurrency:

Five philosophers dine together at the same table. Each philosopher has their own place at the table. There is a fork between each plate. The dish served is a kind of spaghetti which has to be eaten with two forks. Each philosopher can only alternately think and eat. Moreover, a philosopher can only eat their spaghetti when they have both a left and right fork. Thus two forks will only be available when their two nearest neighbors are thinking, not eating. After an individual philosopher finishes eating, they will put down both forks.

You will need a local Cargo installation for this exercise. Copy the code below to a file called src/main.rs, fill out the blanks, and test that cargo run does not deadlock:

  1. use std::sync::{mpsc, Arc, Mutex};
  2. use std::thread;
  3. use std::time::Duration;
  4. struct Fork;
  5. struct Philosopher {
  6.     name: String,
  7.     // left_fork: ...
  8.     // right_fork: ...
  9.     // thoughts: ...
  10. }
  11. impl Philosopher {
  12.     fn think(&self) {
  13.         self.thoughts
  14.             .send(format!("Eureka! {} has a new idea!", &self.name))
  15.             .unwrap();
  16.     }
  17.     fn eat(&self) {
  18.         // Pick up forks...
  19.         println!("{} is eating...", &self.name);
  20.         thread::sleep(Duration::from_millis(10));
  21.     }
  22. }
  23. static PHILOSOPHERS: &[&str] =
  24.     &["Socrates", "Hypatia", "Plato", "Aristotle", "Pythagoras"];
  25. fn main() {
  26.     // Create forks
  27.     // Create philosophers
  28.     // Make each of them think and eat 100 times
  29.     // Output their thoughts
  30. }

You can use the following Cargo.toml:

  1. [package]
  2. name = "dining-philosophers"
  3. version = "0.1.0"
  4. edition = "2021"