使用信号量解决哲学家就餐问题

哲学家就餐问题是由 Edsger Dijkstra 在 1965 年引入的一个经典同步问题。它生动地展示了并发编程中资源共享面临的挑战,例如死锁、饥饿和互斥。

!os

问题描述

  • K 位哲学家围坐在一张圆桌旁。
  • 每位哲学家都在“思考”和“进食”两种状态之间交替。
  • 每两位哲学家之间放着一根筷子(总共 K 根筷子)。
  • 一位哲学家必须拿起两根筷子(左手和右手各一根)才能进食。
  • 同一时间只能有一位哲学家使用一根筷子。

面临的挑战: 设计一种同步机制,使哲学家们能够进食,同时不会导致 死锁(所有人永远等待)或 饥饿(有些人永远没有机会进食)。

问题中的难点

  • 死锁: 如果所有哲学家都先拿起左边的筷子,就没有人能拿到右边的筷子了 —— 这就形成了循环等待。
  • 饥饿: 如果其他哲学家一直占用筷子,某些哲学家可能永远没有机会进食。
  • 并发控制: 必须确保没有两位相邻的哲学家同时进食。

我们可以使用 信号量(Semaphores) 来管理筷子并避免死锁。

算法

  • 每根筷子被表示为一个二进制信号量(互斥锁)。
  • 哲学家必须在进食前获取左手和右手的信号量。
  • 进食结束后,哲学家释放两个信号量。

伪代码

> semaphore chopstick[5] = {1,1,1,1,1};

>

> Philosopher(i):

> while(true) {

> think();

> wait(chopstick[i]); // 拿起左边的筷子

> wait(chopstick[(i+1)%5]); // 拿起右边的筷子

>

> eat();

>

> signal(chopstick[i]); // 放下左边的筷子

> signal(chopstick[(i+1)%5]); // 放下右边的筷子

>

> }

解释:

  • semaphore chopstick[5] = {1,1,1,1,1}; 每根筷子都是一个初始化为 1 的二进制信号量(表示可用)。
  • think(); 哲学家花时间思考。
  • wait(chopstick[i]); 尝试拿起左边的筷子。如果筷子是空闲的,哲学家就拿起它;否则等待。
  • wait(chopstick[(i+1)%5]); 尝试拿起右边的筷子(使用取模运算来模拟圆桌)。
  • eat(); 当两根筷子都拿到后,哲学家开始进食。
  • signal(chopstick[i]);signal(chopstick[(i+1)%5]); P 放下两根筷子,使它们对相邻的哲学家可用。

代码实现

C++


CODEBLOCK_d757932f

Java


import java.util.concurrent.Semaphore;

import java.util.concurrent.TimeUnit;

public class DiningPhilosophers {

private static final int N = 5; // 哲学家数量

private static final Semaphore[] chopstick = new Semaphore[N];

public static void main(String[] args) {

// 初始化筷子信号量

for (int i = 0; i < N; i++) {

chopstick[i] = new Semaphore(1);

}

// 创建哲学家线程

for (int i = 0; i < N; i++) {

new Thread(new Philosopher(i)).start();

}

}

static class Philosopher implements Runnable {

private final int id;

Philosopher(int id) {

this.id = id;

}

@Override

public void run() {

while (true) {

System.out.println("Philosopher " + id + " is thinking…");

sleep(1);

// 拿起左边的筷子

try { chopstick[id].acquire(); } catch (InterruptedException

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/47225.html
点赞
0.00 平均评分 (0% 分数) - 0