فلسفه Dining

مسئله ناهار خوردن فیلسوفان، در واقع یک مسئله کلاسیک concurrency است:

پنج فیلسوف در کنار هم دور یک میز غذا می‌خورند. هر فیلسوف جایگاه خاص خود را در میز دارد. بین هر بشقاب یک چنگال قرار دارد. غذایی که سِرو می‌شود نوعی اسپاگتی است که باید با دو چنگال خورده شود. هر فیلسوف فقط می‌تواند به طور متناوب فکر کند و غذا بخورد. علاوه بر این، یک فیلسوف فقط می‌تواند اسپاگتی خود را زمانی بخورد که هم چنگال چپ و هم چنگال راست را داشته باشد؛ بنابراین دو چنگال فقط زمانی در دسترس خواهد بود که دو همسایه نزدیک آنها در حال فکرکردن باشند و نه در حال غذاخوردن. پس از اینکه یک فیلسوف غذاخوردن را تمام کرد، هر دو چنگال را پایین می‌گذارد.

برای این تمرین به یک Cargo installation محلی نیاز دارید. کد زیر را در فایلی به نام src/main.rs کپی کنید، جاهای خالی را پر کنید و آزمایش کنید که cargo run به بن‌بست (deadlock) نمی‌خورد:

use std::sync::{mpsc, Arc, Mutex};
use std::thread;
use std::time::Duration;

struct Fork;

struct Philosopher {
    name: String,
    // left_fork: ...
    // right_fork: ...
    // thoughts: ...
}

impl Philosopher {
    fn think(&self) {
        self.thoughts
            .send(format!("ایول! {} یک ایده جدید!", &self.name))
            .unwrap();
    }

    fn eat(&self) {
        // Pick up forks...
        println!("{} is eating...", &self.name);
        thread::sleep(Duration::from_millis(10));
    }
}

static PHILOSOPHERS: &[&str] =
    &["Socrates", "Hypatia", "Plato", "Aristotle", "Pythagoras"];

fn main() {
    // Create forks

    // Create philosophers

    // Make each of them think and eat 100 times

    // Output their thoughts
}

می توانید از Cargo.toml زیر استفاده کنید:

[package]
name = "dining-philosophers"
version = "0.1.0"
edition = "2021"