Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Обедающие философы

Задача об обедающих философах — классическая задача конкурентности:

Пять философов обедают за одним столом. У каждого философа есть своё место за столом. Между каждыми двумя тарелками лежит палочка для еды. Подают спагетти, которые едят двумя палочками. Каждый философ может только по очереди думать и есть. Более того, философ может есть свои спагетти, только когда у него есть и левая, и правая палочки. Таким образом, две палочки будут доступны, только когда двое ближайших соседей думают, а не едят. Когда отдельный философ закончит есть, он положит обе палочки.

Для этого упражнения понадобится локальная установка 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"
This slide should take about 20 minutes.
  • Поощряйте студентов сначала сосредоточиться на реализации решения, которое «в основном» работает.
  • Взаимная блокировка в простейшем решении — общая проблема конкурентности, и она показывает, что Rust не предотвращает автоматически такие ошибки.