哲学家就餐问题.docx
- 文档编号:29927358
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:17
- 大小:289.37KB
哲学家就餐问题.docx
《哲学家就餐问题.docx》由会员分享,可在线阅读,更多相关《哲学家就餐问题.docx(17页珍藏版)》请在冰豆网上搜索。
哲学家就餐问题
哲学家就餐问题
数学与计算机学院
课程设计说明书
课程名称:
操作系统原理-课程设计
课程代码:
8404061
题目:
哲学家就餐问题模拟
年级/专业/班:
09级信息与计算科学三班
学生姓名:
徐磊
学 号:
312009*********
开始时间:
2012年05月14日
完成时间:
2012年05月31日
课程设计成绩:
学习态度及平时成绩(30)
技术水平与实际能力(20)
创新(5)
说明书撰写质量(45)
总分(100)
1引言
1.1问题的提出
哲学家进餐问题也是一个经典的同步问题,它是由Dijkstra提出并解决的。
哲学家进餐问题是这样的:
5个哲学家以思考、吃饭交替进行的方式生活,他们共享一张周围有5把椅子的圆桌,每人一把椅子,在桌子上摆有5个饭碗和5只筷子。
当一个哲学家思考时,他不与邻座同事发生联系。
当一哲学家饿了,他就试图拿起他左右两边的筷子吃饭。
显然,他不能拿起已抓在他的邻座手中的筷子,于是,他可能只拿到一只甚至一只筷子也拿不到。
当一个饥饿的哲学家得到了两只筷子,他就可以吃饭。
当他用饭毕,就放下筷子并再次开始思考。
5个哲学家共享5支筷子,最多只能不相邻的两个哲学家同时就餐。
在多道程序设计环境下,进程同步问题十分重要,其中“哲学家进餐问题”是较有代表性的。
通过对该问题的研究学习和实践,可以帮助我们更好的理解和掌握临界资源、进程同步的概念和实现方法。
1.2任务与分析
本课题主要的目的通过实现哲学家进餐问题的同步深入了解和掌握进程同步和互斥的原理。
2.总体设计思想及相关知识
2.1总体设计思想
哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复。
要求是:
每一个哲学家只有在拿到位于他左右筷子,才能够就餐;哲学家只能先拿一只筷子,再去拿另一只筷子,而不能同时去抓他旁边的两只筷子,也不能从其他哲学家手中抢夺筷子;哲学家每次就餐后必须放下他手中的两只筷子后恢复思考,不能强抓住筷子不放。
设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和筷子的使用情况。
即设计一个能安排哲学家正常生活的程序。
为哲学家设计3种状态,即“等待”“进餐”“思考”。
每个哲学家重复进行“等待”->“进餐”->“思考”的行动循环。
其中:
“等待”->“进餐”:
只有一个哲学家处于等待进餐状态,且左右手两边的筷子都处于“空闲”状态时,可以发生这种状态改变。
此状态改变发生后,哲学家拿起左右手两边的筷子。
“进餐”->“思考”:
此状态改变发生后,哲学家放下左右手上的筷子。
筷子状态由“使用中”转变为“空闲”。
“思考”->“等待”:
哲学家思考结束后,无条件转入等待状态。
由上所述,程序中应设置5个元素的信号量数组,chopsticks[5],用来保持哲学家之间的同步。
2.2临界区互斥编程原理
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。
每个进程中访问临界资源的那段代码称为临界区(CriticalSection)。
每个进程中访问临界资源的那段程序称为临界区(CriticalSection)(临界资源是一次仅允许一个进程使用的共享资源)。
每次只准许一个进程进入临界区,进入后不允许其他进程进入。
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。
本程序主要使用了EnterCriticalSection(&cs)和LeaveCriticalSection(&cs)两个函数实现临界区互斥。
EnterCriticalSection(&cs)用来进入临界区,LeaveCriticalSection(&cs)用来离开临界区。
3程序运行平台
VisualStudio2008。
具体操作如下:
新建项目,添加相应的源文件,再编译,链接,执行等。
4程序类的说明
程序中定义一个哲学家类,包含两个私有对象和四个公有对象。
Philosopher
-number:
int
-status:
int
+Philosopher(innum:
int)
+find()const:
int
+getinfo()const:
int
+Change():
void
图4-1哲学家类的UML图
Number对象:
哲学家的编号。
Status对象:
用于保存当前该哲学家的状态,0表示正在等待(即处于饥饿状态)1表示得到餐具正在吃饭,2表示正在思考
Philosopher(intnum)方法:
哲学家类构造函数,参数num表示哲学家编号
find()const方法:
返回该哲学家编号
getinfo()const方法:
返回哲学家当前状态
Change()方法:
根据题目要求改变哲学家的状态(等待->进餐->思考->等待…………)
另外,程序中包含一个公有对象,bool类型数组chopsticks[5],用来保存5只筷子当前状态:
true表示该餐具当前空闲,false表示该餐具当前正被使用。
程序中还包含两个公有函数:
print和chopstickstatus。
Print用来返回一个哲学家的状态,chopstickstatus用来返回一个餐具的状态。
5程序各个模块流程图
5.1主程序模块
图5-1主程序模块流程图
5.2状态改变模块
开始
哲学家处于进餐状态?
Status==1?
否
是
放下左右手的筷子
Chopsticks[number%5]=true
Chopsticks[(number+1)%5]=true
哲学家处于思考状态?
status==2?
否
是
哲学家处于等待状态?
Status==0?
否
是
图5-2状态改变模块Change()流程图
5.3返回哲学家状态图
图5-3返回哲学家状态模块print()流程图
5.4返回餐具状态模块
图5-4返回餐具状态模块chopsticksstatus(boola)流程图
6系统测试
首先进入VisualStudio2008,进入源程序。
生成称解决方案,然后运行。
图6-1哲学家开始状态1
图6-2哲学家状态2
图6-3哲学家状态3
图6-4哲学家状态4
8结论
对自己完成的题目进行总结,包括程序的功能、创新点(与众不同的地方)及程序存在的问题和修改对策。
通过本次课程设计的过程,我了解了金典的同步问题哲学家就餐问题。
发现自己对互斥变量把握不太清楚。
及在编程过程中自己对C++语法的不熟悉。
本程序通过定义一个哲学家类,模拟了哲学家就餐,思考和等待的不同状态。
附录
附录1源程序清单
#include
#include
#include
#include
#include
usingnamespacestd;
boolchopsticks[5];//全局变量,用餐工具
CRITICAL_SECTIONcs;//信号量,在线程中使用,临界区
classPhilosopher
{
private:
intnumber;
intstatus;/*标记当前哲学家的状态,0表示正在等待(即处于饥饿状态),1表示得到两支筷子正在吃饭,2表示正在思考*/
public:
Philosopher(intnum=1):
status
(2),number(num){}
intfind()//定义常成员函数返回该哲学家编号
const
{
returnnumber;
}
intgetinfo()//定义常成员函数返回哲学家当前状态
const
{
returnstatus;
}
voidChange();//状态改变函数
};
voidPhilosopher:
:
Change()
{
EnterCriticalSection(&cs);//进入临界区
if(status==1)//正在进餐
{
chopsticks[(number)%5]=true;//放下左手工具
chopsticks[(number+1)%5]=true;//放下右手工具
status=2;//改变状态为思考
}
elseif(status==2)//思考中
{
status=0;//改变状态为等待
}
elseif(status==0)//等待中
{
if(chopsticks[number%5]&&chopsticks[(number+1)%5])//左右手两边筷子均为空闲状态
{
chopsticks[number%5]=false;//拿起左边的筷子
chopsticks[(number+1)%5]=false;//拿起右边的筷子
status=1;
}
}
LeaveCriticalSection(&cs);//释放临界区
}
stringprint(Philosopher*pA)//返回哲学家状态
{
//pA->Change();
inti=pA->getinfo();
stringstr;
if(i==0)
str="等待";
elseif(i==1)
str="就餐";
elsestr="思考";
returnstr;
}
stringchopstickstatus(boola)//返回筷子状态
{
stringstate;
if(a==true)
state="闲";
if(a==false)
state="用";
returnstate;
}
intmain()
{
charcon='y';//判断是否继续
for(inti=1;i<=5;i++)
chopsticks[i]=true;//5根筷子都未使用,初始化
PhilosopherP1
(1),P2
(2),P3(3),P4(4),P5(5);
InitializeCriticalSection(&cs);//初始化初始化临界区
cout<<"-----------------------状态说明示意图:
-----------------------"< cout<<"哲学家号的状态"<<""<<"筷子的状态"<<""<<"筷子的状态"<<""<<"哲学家号的状态"< cout<<""<<"筷子的状态"< cout<<"哲学家号的状态"<<""<<"筷子的状态"<<""<<"筷子的状态"<<""<<"哲学家号的状态"< cout<<""<<"哲学家号的状态"<<""< cout<<"筷子的状态,“用”表示使用中,“闲”表示空闲中。 "< cout<<"--------------------------"< cout<<"哲学家们开始生活: "< cout< cout< while(con=='y') { P1.Change(); P2.Change(); P3.Change(); P4.Change(); P5.Change(); //P6.Change(); cout<<"当前状态为: "< cout< cout<<""< cout< cout<<""< cout<<"--------------------------"< cout<<"若要继续下一状态,输入y;输入其他,结束程序: "; cin>>con; Sleep(20); } DeleteCriticalSection(&cs);//退出资源区 return0; }
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 哲学家 就餐 问题