5.1 哲学家就餐 — 异步

01-哲学家就餐 — 异步 — Comprehensive Rust

译文 · 基于 Comprehensive Rust

原文链接: https://google.github.io/comprehensive-rust/concurrency/async-exercises/dining-philosophers.html

5.1 哲学家就餐 — 异步

问题描述见哲学家就餐。

与之前一样,本练习需要本地 Cargo 安装。把下面的代码复制到 src/main.rs,填空,并测试 cargo run 不会死锁:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Copyright 2024 Google LLC
// SPDX-License-Identifier: Apache-2.0
use std::sync::Arc;
use tokio::sync::{Mutex, mpsc};
use tokio::time;

struct Chopstick;

struct Philosopher {
    name: String,
    // left_chopstick: ...
    // right_chopstick: ...
    // thoughts: ...
}

impl Philosopher {
    async fn think(&self) {
        self.thoughts
            .send(format!("Eureka! {} has a new idea!", &self.name))
            .await
            .unwrap();
    }

    async fn eat(&self) {
        // 一直尝试直到拿到两根筷子
        // 拿起筷子……

        println!("{} is eating...", &self.name);
        time::sleep(time::Duration::from_millis(5)).await;

        // 锁在此处丢弃
    }
}

// tokio 调度器在 5 位哲学家时不会死锁,因此用 2 位。
static PHILOSOPHERS: &[&str] = &["Socrates", "Hypatia"];

#[tokio::main]
async fn main() {
    // 创建筷子

    // 创建哲学家

    // 让他们思考并进食

    // 输出他们的想法
}

这次使用异步 Rust,因此需要 tokio 依赖。可以使用如下 Cargo.toml:

1
2
3
4
5
6
7
[package]
name = "dining-philosophers-async-dine"
version = "0.1.0"
edition = "2024"

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

另请注意:这次必须使用 tokio crate 中的 Mutex 与 mpsc 模块。

  • 你能做成单线程实现吗?
最后修改 August 11, 2026: 更新 (70a5af133)