[经典进程同步问题]哲学家思考

问题描述

一张圆桌上坐着5名哲学家,每两个哲学家之间的桌上摆一根筷子,桌子的中间是一碗米饭,如图2-10所示。哲学家们倾注毕生精力用于思考和进餐,哲学家在思考时,并不影响他人。只有当哲学家饥饿的时候,才试图拿起左、 右两根筷子(一根一根地拿起)。如果筷子已在他人手上,则需等待。饥饿的哲学家只有同时拿到了两根筷子才可以开始进餐,当进餐完毕后,放下筷子继续思考。

问题分析

1) 关系分析。5名哲学家与左右邻居对其中间筷子的访问是互斥关系。

2) 整理思路。显然这里有五个进程。本题的关键是如何让一个哲学家拿到左右两个筷子而不造成死锁或者饥饿现象。那么解决方法有两个,一个是让他们同时拿两个筷子;二是对每个哲学家的动作制定规则,避免饥饿或者死锁现象的发生。

3) 信号量设置。定义互斥信号量数组Ch0PstiCk[5] = {1, 1, 1, 1, 1}用于对5个筷子的互斥访问。

对哲学家按顺序从0~4编号,哲学家i左边的筷子的编号为i,哲学家右边的筷子的编号为(i+1)%5。

semaphore chopstick[5] = {1,1,1,1,1}; //定义信号量数组chopstick[5],并初始化
Pi()
{  //i号哲学家的进程
    do
	{
        P (chopstick[i] ) ; //取左边筷子
        P (chopstick[(i+1) %5] ) ;  //取右边篌子
        eat;  //进餐
        V(chopstick[i]) ; //放回左边筷子
        V(chopstick[(i+l)%5]);  //放回右边筷子
        think;  //思考
    } while (1);
}

该算法存在以下问题:当五个哲学家都想要进餐,分别拿起他们左边筷子的时候(都恰好执行完wait(chopstick[i]);)筷子已经被拿光了,等到他们再想拿右边的筷子的时候(执行 wait(chopstick[(i+l)%5]);)就全被阻塞了,这就出现了死锁。

为了防止死锁的发生,可以对哲学家进程施加一些限制条件,比如:

至多允许四个哲学家同时进餐;

仅当一个哲学家左右两边的筷子都可用时才允许他抓起筷子;

对哲学家顺序编号,要求奇数号哲学家先抓左边的筷子,然后再转他右边的筷子,而偶数号哲学家刚好相反。

正解制定规则如下:假设釆用第二种方法,当一个哲学家左右两边的筷子都可用时,才允许他抓起筷子。

semaphore chopstick[5] = {1,1,1,1,1}; //初始化信号量
semaphore mutex=l;  //设置取筷子的信号量
Pi()
{ //i号哲学家的进程
    do
	{
        P (mutex) ; //在取筷子前获得互斥量
        P (chopstick [i]) ; //取左边筷子
        P (chopstick[ (i+1) %5]) ;  //取右边筷子
        V (mutex) ; //释放取筷子的信号量
        eat;  //进餐
        V(chopstick[i] ) ;  //放回左边筷子
        V(chopstick[ (i+l)%5]) ;  //放回右边筷子
        think;  // 思考
    }while(1);
}

此外还可以釆用AND型信号量机制来解决哲学家进餐问题,有兴趣的读者可以查阅相关资料,自行思考。

时间: 2024-10-10 23:26:43

[经典进程同步问题]哲学家思考的相关文章

JAVA并发,经典死锁案例-哲学家就餐

转自:http://blog.csdn.net/tayanxunhua/article/details/38691005 死锁经典案例:哲学家就餐. 这个案例会导致死锁. 通过修改<Java编程思想4>一书中的案例,来做实验,代码更易理解,结果也相对容易控制. 附代码: 筷子类: 1 package com.tyxh.ch21.c6; 2 3 public class Chopstick { 4 private boolean taken = false;//判断是此筷子是否被拿起 5 pub

【经典进程同步问题】

1.生产者-消费者问题有一群生产者进程在生产产品,并将这些产品提供给消费者进程去消费.为使生产者进程与消费者进程能并发执行,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将其所生产的产品放入一个缓冲区中:消费者进程可从一个缓冲区中取走产品去消费.尽管所有的生产者进程和消费者进程都是以异步方式运行的,但它们之间必须保持同步,既不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满产品且尚未被取走的缓冲区中投放产品.2.哲学家进餐问题有五个哲学家共用一张圆桌,分别坐在周围的五

经典进程同步问题一:生产者-消费者问题(The producer-consumer problem)

(注:参考教材:计算机操作系统第四版 西安电子科技大学出版社) 问题描述:一群生产者进程在生产产品,并将这些产品提供给消费者去消费.为了使生产者进程与消费者进程能够并发进行,在两者之间设置一个具有n个缓冲区的缓冲池,生产者进程将产品放入一个缓冲区中:消费者可以从一个缓冲区取走产品去消费.尽管所有的生产者进程和消费者进程是以异方式运行,但它们必须保持同步:当一个缓冲区为空时不允许消费者去取走产品,当一个缓冲区满时也不允许生产者去存入产品. 解决方案:我们这里利用一个一个数组buffer来表示这个n

经典进程同步问题

1.生产者-消费者问题 问题描述 两个进程共享一个大小为n的缓冲区,其中一个是生产者,将信息放入缓冲区:另一个是消费者,从缓冲区中取出信息.由于缓冲区是霖姐资源,如何实现缓冲区的互斥访问和生产者.消费者之间的同步? 分析 使用三个信号量: 1.full,记录缓冲区满槽数目,用于同步,初值为0: 2.empty,记录缓冲区空槽数目,初值为n: 3.mutex,用于互斥,初值为1: 生产者和消费者在进去临界区都执行down操作,在刚刚退出时执行up操作,就能实现互斥.同时,对full和empty执行

操作系统原理---操作系统中进程同步和互斥的概念

简介 进程同步是一个操作系统级别的概念,是在多道程序的环境下,存在着不同的制约关系,为了协调这种互相制约的关系,实现资源共享和进程协作,从而避免进程之间的冲突,引入了进程同步. 临界资源 在操作系统中,进程是占有资源的最小单位(线程可以访问其所在进程内的所有资源,但线程本身并不占有资源或仅仅占有一点必须资源).但对于某些资源来说,其在同一时间只能被一个进程所占用.这些一次只能被一个进程所占用的资源就是所谓的临界资源.典型的临界资源比如物理上的打印机,或是存在硬盘或内存中被多个进程所共享的一些变量

Thking in Java---从哲学家就餐问题看死锁现象

我们知道一个对象可以有synchronized方法或其他形式的加锁机制来防止别的线程在互斥还没释放的时候就访问这个对象.而且我们知道线程是会变成阻塞状态的(挂起),所以有时候就会发生死锁的情况:某个任务在等待另一个任务,而后者又在等待其它任务,这样一直下去,知道这个链条下的任务又在等待第一个任务释放锁,这样就形成了一个任务之间相互等待的连续循环,没有任务可以继续的情况.死锁的最大问题在于它发生的几率非常小,并不是我们一运行程序它就死锁了,而是会不知道那个时候程序就死锁了并且我们很难重现当时出现死

哲学家进餐问题

先直接上代码 1 #define N 5 /* 哲学家数目 */ 2 #define LEFT (i+N-1)%N /* i的左邻编号 */ 3 #define RIGHT (i+ 1)%N /* i的右邻编号 */ 4 #define THINKING 0 /* 哲学家在思考 */ 5 #define HUNGRY 1 /*哲学家试图拿起叉子 */ 6 #define EATING 2 /* 哲学家进餐 */ 7 typedef int semaphore; /*信号量 */ 8 int st

Java多线程,哲学家就餐问题

问题描述:一圆桌前坐着5位哲学家,两个人中间有一只筷子,桌子中央有面条.哲学家思考问题,当饿了的时候拿起左右两只筷子吃饭,必须拿到两只筷子才能吃饭.上述问题会产生死锁的情况,当5个哲学家都拿起自己右手边的筷子,准备拿左手边的筷子时产生死锁现象. 解决办法: 1.添加一个服务生,只有当经过服务生同意之后才能拿筷子,服务生负责避免死锁发生. 2.每个哲学家必须确定自己左右手的筷子都可用的时候,才能同时拿起两只筷子进餐,吃完之后同时放下两只筷子. 3.规定每个哲学家拿筷子时必须拿序号小的那只,这样最后

【ThinkingInJava】63、哲学家进餐问题

/** * 书本:<Thinking In Java> * 功能:哲学家进餐问题 * 作为哲学家,他们很穷,所以他们只能买五根筷子.他们围坐在桌子周围,每人之间放一根筷子.当一个哲学家要就餐的时候了,这个哲学家必须同时得到左边 * 和右边的筷子.如果一个哲学家左边或右边的筷子已经有人在使用筷子了,那么这个哲学家就必须等待,直至可以得到必须的筷子 * 文件:Chopstick.java * 时间:2015年5月9日15:08:21 * 作者:cutter_point */ package Les