Обедающие философы
Задача об обедающих философах — классическая задача конкурентности:
Пять философов обедают за одним столом. У каждого философа есть своё место за столом. Между каждыми двумя тарелками лежит палочка для еды. Подают спагетти, которые едят двумя палочками. Каждый философ может только по очереди думать и есть. Более того, философ может есть свои спагетти, только когда у него есть и левая, и правая палочки. Таким образом, две палочки будут доступны, только когда двое ближайших соседей думают, а не едят. Когда отдельный философ закончит есть, он положит обе палочки.
Для этого упражнения понадобится локальная установка Cargo. Скопируйте приведённый ниже код в файл src/main.rs, заполните пропуски и проверьте, что cargo run не приводит к взаимной блокировке (deadlock):
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
use std::sync::{Arc, Mutex, mpsc};
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) {
// Берём палочки...
println!("{} is eating...", self.name);
thread::sleep(Duration::from_millis(10));
}
}
static PHILOSOPHERS: &[&str] =
&["Socrates", "Hypatia", "Plato", "Aristotle", "Pythagoras"];
fn main() {
// Создаём палочки
// Создаём философов
// Заставляем каждого думать и есть 100 раз
// Выводим их мысли
}
Можно использовать следующий Cargo.toml:
[package]
name = "dining-philosophers"
version = "0.1.0"
edition = "2024"
- Поощряйте студентов сначала сосредоточиться на реализации решения, которое «в основном» работает.
- Взаимная блокировка в простейшем решении — общая проблема конкурентности, и она показывает, что Rust не предотвращает автоматически такие ошибки.