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 chopstick between each plate. The dish served is spaghetti which requires two chopsticks to eat. Each philosopher can only alternately think and eat. Moreover, a philosopher can only eat their spaghetti when they have both a left and right chopstick. Thus two chopsticks will only be available when their two nearest neighbors are thinking, not eating. After an individual philosopher finishes eating, they will put down both chopsticks.
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:
use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use std::time::Duration;
struct Chopstick;
struct Philosopher {
name: String,
// left_chopstick: ...
// right_chopstick: ...
// thoughts: ...
}
impl Philosopher {
fn think(&self) {
self.thoughts
.send(format!("Eureka! {} has a new idea!", &self.name))
.unwrap();
}
fn eat(&self) {
// Pick up chopsticks...
println!("{} is eating...", &self.name);
thread::sleep(Duration::from_millis(10));
}
}
static PHILOSOPHERS: &[&str] =
&["Socrates", "Hypatia", "Plato", "Aristotle", "Pythagoras"];
fn main() {
// Create chopsticks
// Create philosophers
// Make each of them think and eat 100 times
// Output their thoughts
}
You can use the following Cargo.toml
:
[package]
name = "dining-philosophers"
version = "0.1.0"
edition = "2021"
Speaker Notes
This slide should take about 20 minutes.
- Encourage students to focus first on implementing a solution that “mostly” works.
- The deadlock in the simplest solution is a general concurrency problem and highlights that Rust does not automatically prevent this sort of bug.