Вечеря філософів --- Async

Перегляньте вечерю філософів для опису проблеми.

Як і раніше, для виконання цієї вправи вам знадобиться локальний встановленний Cargo. Скопіюйте наведений нижче код у файл під назвою src/main.rs, заповніть порожні поля та перевірте, чи cargo run не блокує:

use std::sync::Arc;
use tokio::sync::mpsc::{self, Sender};
use tokio::sync::Mutex;
use tokio::time;

struct Fork;

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

impl Philosopher {
    async fn think(&self) {
        self.thoughts
            .send(format!("Еврика! {} має нову ідею!", &self.name))
            .await
            .unwrap();
    }

    async fn eat(&self) {
        // Продовжуємо пробувати, поки не знайдемо обидві виделки
        println!("{} їсть...", &self.name);
        time::sleep(time::Duration::from_millis(5)).await;
    }
}

static PHILOSOPHERS: &[&str] =
    &["Сократ", "Гіпатія", "Платоне", "Аристотель", "Піфагор"];

#[tokio::main]
async fn main() {
    // Створюємо виделки

    // Створюємо філософів

    // Змусимо їх думати і їсти

    // Вивести свої думки
}

Оскільки цього разу ви використовуєте Async Rust, вам знадобиться залежність tokio. Ви можете використовувати наступний Cargo.toml:

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

[dependencies]
tokio = { version = "1.26.0", features = ["sync", "time", "macros", "rt-multi-thread"] }

Також зауважте, що цього разу вам доведеться використовувати Mutex і модуль mpsc з крейту tokio.

This slide should take about 20 minutes.
  • Чи можете ви зробити вашу реалізацію однопотоковою?