哲学家就餐问题

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
“进餐”->“思考”:此状态改变发生后,哲学家放下左右手上的筷子。筷子状态由“使用中”转变为“空闲”。
“思考”->“等待”:哲学家思考结束后,无条件转入等待状态。
由上所述,程序中应设置5个元素的信号量数组,chopsticks[5],用来保持哲学家之间的同步。
2.2
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。每个进程中访问临界资源的那段代码称为临界区(Critical Section)。
Philosopher
-number:int
-status:int
+Philosopher(innum:int)
+find() const:int
+getinfo() const:int
+Change():void
图4-1哲学家类的UML图
Number对象:哲学家的编号。
Status对象:用于保存当前该哲学家的状态,0表示正在等待(即处于饥饿状态)1表示得到餐具正在吃饭,2表示正在思考
数学与计算机学院
课程设计说明书
课 程 名 称:操作系统原理-课程设计
课 程 代 码:8404061
题 目:哲学家就餐问题模拟
年级/专业/班:09级信息与计算科学三班
学 生 姓 名:徐磊
学 号:312009070102301
开 始 时 间:2012年05月14日
完 成 时 间:2012年05月31日
课程设计成绩:
chopsticks[number%5]=false;//拿起左边的筷子
chopsticks[(number+1)%5]=false;//拿起右边的筷子
status=1;
}
}
LeaveCriticalSection (&cs) ;//释放临界区
}
string print(Philosopher *pA)//返回哲学家状态
}
voidChange() ;//状态改变函数
};
voidPhilosopher::Change()
{
EnterCriticalSection (&cs) ;//进入临界区
if(status==1)//正在进餐
{
chopsticks[(number)%5]=true;//放下左手工具
chopsticks[(number+1)%5]=true;//放下右手工具
boolchopsticks[5];//全局变量,用餐工具
CRITICAL_SECTION cs;//信号量,在线程中使用,临界区
classPhilosopher
{
private:
intnumber;
intstatus;/*标记当前哲学家的状态,0表示正在等待(即处于饥饿状态),1表示得到两支筷子正在吃饭,2表示正在思考*/
{
//pA->Change();
inti=pA->getinfo();
string str;
if(i==0)
str="等待";
elseif(i==1)
str="就餐";
elsestr="思考";
returnstr;
}
string chopstickstatus(boola)//返回筷子状态
{
string state;
P5.Change();
//P6.Change();
cout<<"当前状态为:"<<endl;
cout<<P1.find()<<print(&P1)<<""<<chopstickstatus(chopsticks[1])<<""<<chopstickstatus(chopsticks[2])<<""<<P2.find()<<print(&P2)<<endl;
Philosopher(intnum)方法:哲学家类构造函数,参数num表示哲学家编号
find() const方法:返回该哲学家编号
getinfo() const方法:返回哲学家当前状态
Change()方法:根据题目要求改变哲学家的状态(等待->进餐->思考->等待…………)
另外,程序中包含一个公有对象,bool类型数组chopsticks[5],用来保存5只筷子当前状态:true表示该餐具当前空闲,false表示该餐具当前正被使用。
学习态度及平时成绩(30)
技术水平与实际能力(20)
创新(5)
说明书撰写质量(45)
总 分(100)
指导教师签名:年月日
1
1.1
哲学家进餐问题也是一个经典的同步问题,它是由Dijkstra提出并解决的。哲学家进餐问题是这样的:5个哲学家以思考、吃饭交替进行的方式生活,他们共享一张周围有5把椅子的圆桌,每人一把椅子,在桌子上摆有5个饭碗和5只筷子。当一个哲学家思考时,他不与邻座同事发生联系。当一哲学家饿了,他就试图拿起他左右两边的筷子吃饭。显然,他不能拿起已抓在他的邻座手中的筷子,于是,他可能只拿到一只甚至一只筷子也拿不到。当一个饥饿的哲学家得到了两只筷子,他就可以吃饭。当他用饭毕,就放下筷子并再次开始思考。5个哲学家共享5支筷子,最多只能不相邻的两个哲学家同时就餐。
cout<<"--------------------------"<<endl;
cout<<"哲学家们开始生活:"<<endl;
cout<<endl;
cout<<endl;
while(con=='y')
{
P1.Change();
P2.Change();
P3.Change();
P4.Change();
return0;
}
public:
Philosopher(intnum=1): status(2), number(num) { }
intfind()//定义常成员函数返回该哲学家编号
const
{
returnnumber;
}
intgetinfo()//定义常成员函数返回哲学家当前状态
const
{
returnstatus;
EnterCriticalSection (&cs)用来进入临界区,LeaveCriticalSection (&cs)用来离开临界区。
3 程序运行平台
Visual Studio 2008。
具体操作如下:新建项目,添加相应的源文件,再编译,链接,执行等。
4
程序中定义一个哲学家类,包含两个私有对象和四个公有对象。
6
首先进入Visual Studio 2008,进入源程序。生成称解决方案,然后运行。
图6-1哲学家开始状态1
图6-2哲学家状态2
图6-3哲学家状态3
图6-4哲学家状态4
8结论
对自己完成的题目进行总结,包括程序的功能、创新点(与众不同的地方)及程序存在的问题和修改对策。
通过本次课程设计的过程,我了解了金典的同步问题哲学家就餐问题。发现自己对互斥变量把握不太清楚。及在编程过程中自己对C++语法的不熟悉。
在多道程序设计环境下,进程同步问题十分重要,其中“哲学家进餐问题”是较有代表性的。通过对该问题的研究学习和实践,可以帮助我们更好的理解和掌握临界资源、进程同步的概念和实现方法。
1.2
本课题主要的目的通过实现哲学家进餐问题的同步深入了解和掌握进程同步和互斥的原理。
2.
2.1
哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复。要求是:每一个哲学家只有在拿到位于他左右筷子,才能够就餐;哲学家只能先拿一只筷子,再去拿另一只筷子,而不能同时去抓他旁边的两只筷子,也不能从其他哲学家手中抢夺筷子;哲学家每次就餐后必须放下他手中的两只筷子后恢复思考,不能强抓住筷子不放。
InitializeCriticalSection (&cs) ;//初始化初始化临界区
cout<<"-----------------------状态说明示意图:-----------------------"<<endl;
cout<<"哲学家号的状态"<<""<<"筷子的状态"<<""<<"筷子的状态"<<""<<"哲学家号的状态"<<endl;
cout<<""<<P5.find()<<print(&P5)<<""<<endl;
cout<<"--------------------------"<<endl;
cout<<"若要继续下一状态,输入y;输入其他,结束程序:";
cin>>con;
Sleep(20);
}
DeleteCriticalSection (&cs) ;//退出资源区
每个进程中访问临界资源的那段程序称为临界区(Critical Section)(临界资源是一次仅允许一个进程使用的共享资源)。每次只准许一个进程进入临界区,进入后不允许其他进程进入。不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。
本程序主要使用了EnterCriticalSection (&cs)和LeaveCriticalSection (&cs)两个函数实现临界区互斥。
设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和筷子的使用情况。即设计一个能安排哲学家正常生活的程序。
为哲学家设计3种状态,即“等待”“进餐”“思考”。每个哲学家重复进行“等待”->“进餐”->“思考”的行动循环。其中:
“等待”->“进餐”:只有一个哲学家处于等待进餐状态,且左右手两边的筷子都处于“空闲”ห้องสมุดไป่ตู้态时,可以发生这种状态改变。此状态改变发生后,哲学家拿起左右手两边的筷子。
status=2;//改变状态为思考
}
elseif(status==2)//思考中
{
status=0;//改变状态为等待
}
elseif(status==0)//等待中
{
if(chopsticks[number%5]&&chopsticks[(number+1)%5])//左右手两边筷子均为空闲状态
{
本程序通过定义一个哲学家类,模拟了哲学家就餐,思考和等待的不同状态。
附 录
附录1 源程序清单
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#include<string>
#include<iostream>
usingnamespacestd;
if(a==true)
state="闲";
if(a==false)
state="用";
returnstate;
}
intmain()
{
charcon ='y';//判断是否继续
for(inti=1;i<=5;i++)
chopsticks[i]=true;//5根筷子都未使用,初始化
Philosopher P1(1),P2(2),P3(3),P4(4),P5(5);
cout<<""<<chopstickstatus(chopsticks[5])<<""<<endl;
cout<<P3.find()<<print(&P3)<<""<<chopstickstatus(chopsticks[3])<<""<<chopstickstatus(chopsticks[4])<<""<<P4.find()<<print(&P4)<<endl;
cout<<""<<"筷子的状态"<<endl;
cout<<"哲学家号的状态"<<""<<"筷子的状态"<<""<<"筷子的状态"<<""<<"哲学家号的状态"<<endl;
cout<<""<<"哲学家号的状态"<<""<<endl;
cout<<"筷子的状态,“用”表示使用中,“闲”表示空闲中。"<<endl;
程序中还包含两个公有函数:print和chopstickstatus。Print用来返回一个哲学家的状态,chopstickstatus用来返回一个餐具的状态。
5
5
图5-1主程序模块流程图
5
图5-2状态改变模块Change()流程图
5
图5-3返回哲学家状态模块print()流程图
5
图5- 4返回餐具状态模块chopsticksstatus(bool a)流程图
相关文档
最新文档