Dining Philosophers —- Async

See dining philosophers for a description of the problem.

As before, 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::Arc;
  2. use tokio::sync::{mpsc, Mutex};
  3. use tokio::time;
  4. struct Fork;
  5. struct Philosopher {
  6.     name: String,
  7.     // left_fork: ...
  8.     // right_fork: ...
  9.     // thoughts: ...
  10. }
  11. impl Philosopher {
  12.     async fn think(&self) {
  13.         self.thoughts
  14.             .send(format!("Eureka! {} has a new idea!", &self.name))
  15.             .await
  16.             .unwrap();
  17.     }
  18.     async fn eat(&self) {
  19.         // Keep trying until we have both forks
  20.         println!("{} is eating...", &self.name);
  21.         time::sleep(time::Duration::from_millis(5)).await;
  22.     }
  23. }
  24. static PHILOSOPHERS: &[&str] =
  25.     &["Socrates", "Hypatia", "Plato", "Aristotle", "Pythagoras"];
  26. #[tokio::main]
  27. async fn main() {
  28.     // Create forks
  29.     // Create philosophers
  30.     // Make them think and eat
  31.     // Output their thoughts
  32. }

Since this time you are using Async Rust, you’ll need a tokio dependency. You can use the following Cargo.toml:

  1. [package]
  2. name = "dining-philosophers-async-dine"
  3. version = "0.1.0"
  4. edition = "2021"
  5. [dependencies]
  6. tokio = { version = "1.26.0", features = ["sync", "time", "macros", "rt-multi-thread"] }

Also note that this time you have to use the Mutex and the mpsc module from the tokio crate.

This slide should take about 20 minutes.

  • Can you make your implementation single-threaded?