`
胖好汉
  • 浏览: 6536 次
社区版块
存档分类
最新评论

哲学家

 
阅读更多

哲学家就餐问题是经典的进程同步问题,而以下解决思路也堪称经典。 

 

n  哲学家进餐问题

n  解决思路1:只允许4位哲学家同时拿筷子。此时必然有一个哲学家能拿到2根筷子。

n  如何保证只有4位哲学家同时拿筷子?

n  可以设置一个初值为4的资源信号量。比如,4张椅子,哲学家进餐之前必须先拿到椅子才能做到桌前拿筷子。进餐完毕后,不但要释放筷子,还要释放椅子。

n  哲学家进餐问题

n  解决思路1:只允许4位哲学家同时拿筷子。此时必然有一个哲学家能拿到2根筷子。

n  var chopstick: array[0…4] of semaphore :=(1,1,1,1,1);

n      chair: semaphore := 4;

n  philosopher(i): begin

n    repeat

n      think;

n      wait(chair); //拿椅子

n      wait(chopstick[i]);

n      wait(chopstick[(i+1) mod 5]);                                        

n      eat;                                      

n      signal(chopstick[i]);                     

n      signal(chopstick[(i+1) mod 5]);

n      signal(chair);//释放椅子                  

n    until false;

n  end

n  哲学家进餐问题:解决思路1

n  椅子这种资源信号量可以减少个数。极端的情况是chair初值为1,即只有一把椅子,那么每次只允许一个哲学家进餐,肯定不会饿死,但是效率低。

 

n  哲学家进餐问题:

n  解决思路2:只有哲学家同时能够拿起左右两边的筷子的时候,才允许拿筷子。

n  此思路最简单的办法是用AND信号量解决。不过本次我们考虑用记录型信号量解决的办法。

n  关键词:原子操作。我们想办法使得哲学家拿左边和右边筷子的过程变得不受打扰。

n  哲学家进餐问题:解决思路2

n  如何让拿两边筷子的动作变成一个原子操作?

n  桌边配备一名服务员,饥饿时招呼一个服务员过来帮哲学家拿筷子。服务员拿完左右两边的筷子就可以去帮助其他人服务。

n  哲学家进餐问题

n  解决思路2:只有哲学家同时能够拿起左右两边的筷子的时候,才允许拿筷子。

n  var chopstick: array[0…4] of semaphore :=(1,1,1,1,1);

n      mutex := 1;

n  philosopher(i): begin

n    repeat

n      think;

n      wait(mutex); //招呼服务员过来

n      wait(chopstick[i]);

n      wait(chopstick[(i+1) mod 5]);

n          signal(mutex);//服务员拿完筷子可以给其他人服务                                     

n      eat;                                      

n      signal(chopstick[i]);                     

n      signal(chopstick[(i+1) mod 5]);        

n    until false;

n  end

n  哲学家进餐问题:解决思路2

如果释放服务员的操作在释放筷子之后进行,而不是在吃饭前进行,则演变成了竞争椅子的极端情况(1把椅子)

n  哲学家进餐问题:解决思路2

n  这种方法的问题:假设0号哲学家正在用餐,此时1号和2号哲学家饥饿了,两者同时招呼服务员。最终服务员为1号服务,但因被0号哲学家占用的1号筷子未释放,因此1号哲学家无法就餐,但他也没有释放服务员。本来2号哲学家有机会吃饭的,但因为没有招呼到服务员,因此必须等待。

n  哲学家进餐问题:解决思路2

n  解决该问题的方法:服务员只有在确认左右两边哲学家都没就餐时才会帮该哲学家拿筷子,否则该哲学家释放服务员。

下面用类C实现这种方法,在该方法中,不使用筷子信号量,而是为每个哲学家设置一个状态位,该状态位可以为THINKINGEATING状态。状态位必须被互斥访问。

 

#define N 5  //哲学家数

#define LEFT (i+N-1) % N //i个哲学家左邻居编号

#define RIGHT (i+1) % N //右邻居编号

#define THINKING 0  //思考状态

#define EATING 1     //吃饭状态

int state[N]; // 定义哲学家状态,初始值为0,即思考状态

semaphore mutex =1; //状态位的互斥信号量

void philosopher(int i){

  while(true){

    think();

    take_chop(i);//拿两支筷子

    eat();

    put_chop(i);//放下两支筷子

  }

}

 

void take_chop(int i){

  wait(mutex);//进入临界区

  if((state[LEFT]!=EATING) && (state[RIGHT]!= EATING)){

    state[i]=EATING;//如果左右两边哲学家都没吃饭,则i可吃饭

  }

  signal(mutex);

}

void put_chop(int i){

  wait(mutex);

  state[i] = THINKING;//吃完饭释放筷子

  signal(mutex);

}

 

 

n  哲学家进餐问题:

n  解决思路3:奇数号哲学家先拿左边筷子,偶数号哲学家先拿右边筷子。(或者相反)

n  此时五位哲学家总是先竞争奇数号筷子,获得后再竞争偶数号筷子。

n  var chopstick: array[0…4] of semaphore :=(1,1,1,1,1);

n  philosopher(i): begin

n    repeat

n      think;

n      wait(chopstick[(i+(i+1) mod 2) mod 5]);

n      wait(chopstick[(i+(i mod 2)) mod 5]);

n      eat;                                      

n      signal(chopstick[(i+(i+1) mod 2) mod 5]);      

n      signal(chopstick[(i+(i mod 2)) mod 5]);

n  until false;

n  end

n  哲学家进餐问题:解决思路3

n  思路3的一些变种:

n  任意一位哲学家与其他哲学家反方向申请筷子

先拿筷子的三位哲学家与后面两位哲学家反方向申请筷子。

分享到:
评论

相关推荐

    哲学家就餐问题源程序

    哲学家就餐问题是一个经典的多线程同步问题,源自计算机科学中的并发控制理论。该问题由Edsger Dijkstra提出,用以模拟五个哲学家在餐桌上的就餐行为:他们每个人都有两只手,一只用来拿筷子(或刀叉),而餐桌上有...

    操作系统 哲学家进餐问题 实现 1 输入饥饿哲学家 2 停止就餐 3 显示个哲学家的状态

    操作系统中的“哲学家进餐问题”是一个经典的同步问题,它由计算机科学家Edsger Dijkstra在1965年提出,用于模拟并发进程的竞争条件。在这个问题中,五位哲学家围坐在一张圆桌旁,每人面前有一根筷子。他们交替地...

    java哲学家就餐问题

    Java哲学家就餐问题是一个经典的多线程同步问题,源自计算机科学家Dijkstra提出的一个思想实验。在该问题中,五个哲学家围坐在一张圆桌旁,每人面前有一根筷子。他们交替进行思考和吃饭,但必须拿到左右两边的两根...

    哲学家就餐问题

    哲学家就餐问题是操作系统领域中一个经典的多线程同步问题,由计算机科学家Edsger Dijkstra在1965年提出,旨在模拟并发哲学家在共用餐桌上的行为,以此来探讨并发控制和死锁的问题。在这个问题中,每位哲学家都有两...

    哲学家吃饭问题C++编程实现

    哲学家吃饭问题,又称Dining Philosophers Problem,是操作系统领域中的一个经典同步问题,由计算机科学家Edsger W. Dijkstra提出。这个问题旨在探讨多线程环境下的资源竞争与死锁问题。在这个问题中,有五个哲学家...

    哲学家进餐.c

    哲学家就餐问题可以这样表述,假设有五位哲学家围坐在一张圆形餐桌旁,做以下两件事情之一:吃饭,或者思考。吃东西的时候,他们就停止思考,思考的时候也停止吃东西。餐桌中间有一大碗意大利面,每两个哲学家之间有...

    C#哲学家就餐问题

    《C#实现哲学家就餐问题详解》 哲学家就餐问题是计算机科学中经典的多线程并发问题,由Edsger W. Dijkstra在1965年提出,旨在模拟多个哲学家在同一时间吃饭的情景,避免他们因筷子争夺而无法进食。在本案例中,我们...

    操作系统哲学家问题操作系统

    根据提供的信息,我们可以深入探讨操作系统中的“哲学家就餐问题”及其解决方案。 ### 操作系统哲学家问题 #### 1. 哲学家就餐问题简介 哲学家就餐问题是一个经典的计算机科学问题,通常用来阐述并发控制中的死锁...

    哲学家多线程

    "哲学家多线程"是一种经典的并发编程问题,源自计算机科学家Dijkstra提出的一个思想实验,旨在探讨并发系统中的资源竞争和死锁问题。在Java中,我们可以通过使用线程和对象间的同步机制来解决这个问题。 首先,让...

    哲学家就餐问题模拟

    哲学家就餐问题(Dining Philosophers Problem)是操作系统设计中一个经典的同步问题,它由计算机科学家Edsger W. Dijkstra提出,旨在探讨多线程环境下的资源竞争和死锁问题。在这个问题中,五个哲学家围坐在一张...

    JAVA实现哲学家就餐问题

    ### JAVA实现哲学家就餐问题详解 #### 背景与问题描述 哲学家就餐问题是一个经典的并发编程问题,由Edsger Dijkstra提出,用于演示死锁、饥饿、竞态条件等多线程同步问题。场景设定为五位哲学家围坐在圆桌旁,桌上...

    6个哲学家就餐问题原代码

    《6个哲学家就餐问题原代码》 哲学家就餐问题是多线程编程中经典的一个死锁问题,它展示了并发操作中可能出现的资源竞争与死锁现象。在这个问题中,我们有6位哲学家围坐在一张圆桌旁,每位哲学家需要两支筷子才能...

    哲学家就餐问题是一个经典的同步问题,用多线程编程实现哲学家就餐问题

    哲学家就餐问题(Dining Philosophers Problem)是计算机科学中多线程与并发控制领域的一个经典示例,由美国计算机科学家Edsger Dijkstra在1965年提出。这个问题模拟了五个哲学家围坐在一张圆桌旁,每个人面前都有一...

    哲学家进餐的设计与实现

    哲学家进餐问题是一个经典的多线程同步问题,由计算机科学家Edsger W. Dijkstra在1965年提出,旨在模拟五个哲学家在共享餐桌上的行为。在这个问题中,每个哲学家有两种状态:思考和吃饭。他们坐在一张圆桌旁,每人有...

    操作系统课程设计哲学家进餐问题报告

    操作系统课程设计中的“哲学家进餐问题”是一个经典的并发控制问题,旨在模拟多个进程竞争共享资源的情景。在这个问题中,哲学家们坐在一张圆桌旁,每人在思考间隙需要拿起左右两边的刀叉来进餐。为了防止死锁,即...

    哲学家进餐问题,操作系统

    "哲学家进餐问题,操作系统" 哲学家进餐问题是计算机科学中的一种经典问题,它是由美国计算机科学家Edsger Dijkstra在1965年提出的。该问题模拟了五位哲学家围坐在圆桌旁,每人面前有一筷子,哲学家们需要拿起左右...

    linux 下qt实现哲学家问题

    本项目旨在利用Qt实现一个C++的多线程应用,来模拟并解决著名的“哲学家就餐问题”(Dining Philosophers Problem)。 哲学家就餐问题是计算机科学中的一个经典同步问题,由Edsger W. Dijkstra提出,用来阐述并发...

    c语言实现哲学家就餐问题

    ### c语言实现哲学家就餐问题 #### 实验背景与目的 **哲学家就餐问题**是计算机科学中的一个经典问题,通常用于演示并发控制中的死锁现象。这个问题涉及到五个哲学家和五个放在他们之间的筷子(或者叉子),每个...

    哲学家就餐(死锁与非死锁解法)(图形界面)

    在 windows 环境下,利用高级语言编程环境(限定为 VS 环境或 VC 环境或QT)调用 CreateThread 函数哲学家就餐问题的演示。要求:(1)提供死锁的解法和非死锁的解法;(2)有图形界面直观显示哲学家取筷子,吃饭,...

Global site tag (gtag.js) - Google Analytics