用C语言实现哲学家进餐的问题

时间:2011-06-24 关注公众号 来源:网络

  设有5个哲学家,共享一张放油把椅子的桌子,每人分得一吧椅子.但是桌子上总共执友支筷子,在每个人两边分开各放一支.哲学家只有在肚子饥饿时才试图分两次从两边拾起筷子就餐.

  就餐条件是:

  1)哲学家想吃饭时,先提出吃饭的要求;

  2)提出吃饭要求,并拿到支筷子后,方可吃饭;

  3)如果筷子已被他人获得,则必须等待该人吃完饭之后才能获取该筷子;

  4)任一哲学家在自己未拿到2支筷子吃饭之前,决不放下手中的筷子;

  5)刚开始就餐时,只允许2个哲学家请求吃饭.

  试问:

  1)描述一个保证不会出现两个邻座同时要求吃饭的算法;

  2)描述一个既没有两邻座同时吃饭,又没有人饿死的算法;

  3)在什么情况下,5个哲学家全都吃不上饭?

  哲学家进餐问题是典型的同步问题.它是由Dijkstra提出并解决的.该问题是描述有五个哲学家,他们的生活方式是交替地进行思考和进餐.哲学家们共用一张圆桌,分别坐在周围的五张椅子上.在圆桌上有五个碗和五支筷子,平时一个哲学家进行思考,饥饿时便试图取用其左右岁靠近他的筷子,只有在他拿到两支筷子时才能进餐.进餐完毕,放下筷子继续思考.

  利用记录型信号量解决哲学家进餐问题

  经分析可知,筷子是临界资源,在一段时间只允许一个哲学家使用.因此,可以用一个信号量表示一支筷子,由这五个信号量构成信号量数组.其描述如下:

  var chopstick:array[0,...,4]of semaphore;

  所有信号量被初始化为1,第i个哲学家的活动可描述为:

  repeat

  wait(chopstick);

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

  ...

  eat;

  ...

  signal(chopstick);

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

  ...

  think;

  until false;

  在以上描述中,哲学家饥饿时,总是先去拿他左边的筷子,即执行wait(chopstick);成功后,再去拿他右边的筷子,即执行wait(chopstick[(i+1) mod 5]);,再成功后便可进餐.进餐完毕,又先放下他左边的筷子,然后放下他右边的筷子.虽然,上述解法可保证不会有两个相临的哲学家同时进餐,但引起死锁是可能的.假如五个哲学家同时饥饿而各自拿起右边的筷子时,就会使五个信号量chopstick均为0;当他们试图去拿右边的筷子时,都将因无筷子可拿而无限期地等待.对于这样的死锁问题可采用以下集中解决方法:

  (1)至多只允许四个哲学家同时进餐,以保证至少有一个哲学家能够进餐,最终总会释放出他所使用过的两支筷子,从而可使更多的哲学家进餐.

  (2)仅当哲学家的左右两支筷子都可用时,才允许他拿起筷子进餐.

  (3)规定奇数号的哲学家先拿起他左边的筷子,然后再去拿他右边的筷子;而偶数号的哲学家则相反.按此规定,将是1,2号哲学家竞争1号筷子,3,4号哲学家竞争3号筷子.即五个哲学家都竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一个哲学家能获得两支筷子而进餐.

  看了整整一个上午的操作系统,看得头都大了。

  我们老师的算法的大意好像是用一个总的信号量,只有获得信号量的哲学家才可以拿筷子。

  具体算法如下(用类c描述):

  #include "所有头文件"

  #define N 5

  #define left (i-1)%N //i的左邻号码

  #define right (i+1)%N //i的右邻号码

  #define think 0

  #define hungry 1

  #define eating 2

  typedef int semaphore //信号量是一个特殊的整型变量

  int state[N] //记录每个人的状态

  semaphore mutex=1; //设置信号量

  semaphore s[N]; //每个哲学家一个信号量

  void philosopher(int i)

  {

  while(true) //无限循环

  {

  think;

  take_chopstick(i);

  eat;

  put_chopstick(i);

  }

  }

  void take_chopstick(int i)

  {

  p(& mutex); //对信号量的p操作

  state=hungry;

  test(i); //试图得到两支筷子

  v(&mutex); //v操作

  p(&s); //得不到筷子则阻塞

  }

  void put_chopstick(int i)

  {

  p(& mutex);

  state=think; //进餐结束

  test(left); //看左邻是否进餐

  test(right); //再看右邻

  v(&mutex);

  }

  void test(int i)

  {

  if(state==hungry&&左邻没进餐&&右邻没进餐)

  {

  state=eating;

  v(&s);

  }

  }

阅读全文
扫码关注“ 多特资源库
更多更全的软件资源下载
文章内容来源于网络,不代表本站立场,若侵犯到您的权益,可联系我们删除。(本站为非盈利性质网站)
玩家热搜
推特怎么注册?推特怎么注册
10086最怕哪个投诉电话?怎么投诉10086最有效方法介绍
gg修改器怎么用教学
超自然异常钥匙在哪里?超自然异常游戏教堂修女关通关流程图文攻略大全
testflight坚果加速器
试眼镜的app哪个好
《为妃作宰》物品获得攻略
面对“台独”势力分裂活动和外部势力干涉台湾事务的严重挑衅,我们坚决开展反分裂、反干涉重大斗争,展示了我们维护国家主权和领土完整、反对“台独”的坚强决心和强大能力,进一步掌握了()的战略主动,进一步巩固了国际社会坚持一个中国的格局。
《一夜成名》换装攻略
面对“台独”势力分裂活动和外部势力干涉台湾事务的严重挑衅,我们坚决开展反分裂、反干涉重大斗争,展示了我们维护国家主权和领土完整、反对“台独”的坚强决心和强大能力,进一步掌握了实现祖国完全统一的战略主动,进一步巩固了国际社会坚持()的格局。
面对国际局势急剧变化,特别是面对外部讹诈、遏制、封锁、极限施压,我们坚持()为重、国内政治优先,保持战略定力,发扬斗争精神,展示不畏强权的坚定意志,在斗争中维护国家尊严和核心利益,牢牢掌握了我国发展和安全主动权。
面对国际局势急剧变化,特别是面对外部讹诈、遏制、封锁、极限施压,我们坚持国家利益为重、国内政治优先,保持(),发扬斗争精神,展示不畏强权的坚定意志,在斗争中维护国家尊严和核心利益,牢牢掌握了我国发展和安全主动权。

相关攻略

正在加载中
版权
版权说明

文章内容来源于网络,不代表本站立场,若侵犯到您的权益,可联系我们删除。(本站为非盈利性质网站)

电话:13918309914

QQ:1967830372

邮箱:[email protected]

toast