范例课程设计哲学家进餐问题Word文档格式.docx
《范例课程设计哲学家进餐问题Word文档格式.docx》由会员分享,可在线阅读,更多相关《范例课程设计哲学家进餐问题Word文档格式.docx(15页珍藏版)》请在冰点文库上搜索。
5.测试及结果11
6.课设总结14
7.参考文献15
1.设计题目与要求
1.1实验目的
通过实现哲学家进餐问题的同步深入了解和掌握进程同步和互斥的原理。
1.2设计要求
哲学家有N个,也定全体到达后开始讨论:
在讨论的间隙哲学家进餐,每人进餐时都需使用刀、叉各一把,所有哲学家刀和叉都拿到后才能进餐。
哲学家的人数、餐桌上的布置自行设定,实现刀和叉的互斥使用算法的程序实现。
1.3初始条件
(1)操作系统:
windows
(2)程序设计语言:
C++
(3)设定圆桌上有六个哲学家,三对刀叉,如下图摆放:
图1-1哲学家进餐问题设定图
2.总体设计思想及相关知识
2.1总体设计思想
哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复。
要求是:
每一个哲学家只有在拿到位于他左右的刀叉后,才能够就餐;
哲学家只能先拿一把刀或叉,再去拿另一把刀或叉,而不能同时去抓他旁边的两把餐具,也不能从其他哲学家手中抢夺餐具;
哲学家每次就餐后必须放下他手中的两把餐具后恢复思考,不能强抓住餐具不放。
设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上餐具的使用情况。
即设计一个能安排哲学家正常生活的程序。
为哲学家设计3种状态,即“等待”“进餐”“思考”。
每个哲学家重复进行“等待”->
“进餐”->
“思考”的行动循环。
其中:
“等待”->
“进餐”:
只有一个哲学家处于等待进餐状态,且左右手两边的餐具都处于“空闲”状态时,可以发生这种状态改变。
此状态改变发生后,哲学家拿起左右手两边的餐具。
“思考”:
此状态改变发生后,哲学家放下左右手上的餐具。
餐具状态由“使用中”转变为“空闲”。
“思考”->
“等待”:
哲学家思考结束后,无条件转入等待状态。
由上所述,程序中应设置6个元素的信号量数组,tools[6],用来保持哲学家之间的同步。
2.2临界区互斥编程原理
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。
每个进程中访问临界资源的那段代码称为临界区(CriticalSection)。
每个进程中访问临界资源的那段程序称为临界区(CriticalSection)(临界资源是一次仅允许一个进程使用的共享资源)。
每次只准许一个进程进入临界区,进入后不允许其他进程进入。
本程序主要使用了EnterCriticalSection(&
cs)和LeaveCriticalSection(&
cs)两个函数实现临界区互斥。
EnterCriticalSection(&
cs)用来进入临界区,LeaveCriticalSection(&
cs)用来离开临界区。
2.3开发环境与工具
系统平台:
WINDOW环境
实现语言:
开发工具:
VC++6.0
3.数据结构与模块说明
3.1数据结构
Philosopher
-number:
int
-status:
+Philosopher(innum:
int)
+find()const:
+getinfo()const:
+Change():
void
图3-1哲学家类的UML图
程序中定义一个哲学家类,包含两个私有对象和四个公有对象。
Number对象:
报讯哲学家的编号。
Status对象:
用于保存当前该哲学家的状态,0表示正在等待(即处于饥饿状态)1表示得到餐具正在吃饭,2表示正在思考
Philosopher(intnum)方法:
哲学家类构造函数,参数num表示哲学家编号
find()const方法:
返回该哲学家编号
getinfo()const方法:
返回哲学家当前状态
Change()方法:
根据题目要求改变哲学家的状态(等待->
进餐->
思考->
等待…………)
另外,程序中包含一个公有对象,bool类型数组tools[6],用来保存6把餐当前状态:
true表示该餐具当前空闲,false表示该餐具当前正被使用。
程序中还包含两个公有函数:
print和toolstatus。
Print用来返回一个哲学家的状态,toolstatus用来返回一个餐具的状态。
3.2程序各模块流程图
3.2.1主程序模块
图3-2主程序模块流程
3.2.2状态改变模块
图3-3状态改变模块Change()流程图
3.2.3返回哲学家状态模块
图3-4返回哲学家状态模块print()流程图
3.2.4返回餐具状态模块
图3-5返回餐具状态模块toolstatus(boola)流程图
4.源程序代码
//实验目的:
//设计要求:
在讨论的间隙哲学家进餐,
//每人进餐时都需使用刀、叉各一把,所有哲学家刀和叉都拿到后才能进餐。
哲学家的人数、
//餐桌上的布置自行设定,实现刀和叉的互斥使用算法的程序实现。
#include<
windows.h>
time.h>
string>
iostream>
assert.h>
usingnamespacestd;
booltools[6];
//全局变量,用餐工具
CRITICAL_SECTIONcs;
//信号量,在线程中使用,临界区
classPhilosopher
{
private:
intnumber;
intstatus;
/*标记当前哲学家的状态,0表示正在等待(即处于饥饿状态),1表示得到两支筷子正在吃饭,2表示正在思考*/
public:
Philosopher(intnum=0):
status
(2),number(num){}
intfind()const{returnnumber;
}
intgetinfo()const{returnstatus;
voidChange();
//状态改变函数
};
voidPhilosopher:
:
Change()
EnterCriticalSection(&
cs);
//进入临界区
if(status==1)//正在进餐
{
tools[number%6]=true;
//放下左手工具
tools[(number-1)%6]=true;
//放下右手工具
status=2;
//改变状态为思考
}
elseif(status==2)//思考中
{
status=0;
//改变状态为等待
}
elseif(status==0)//等待中
if(tools[number%6]&
&
tools[(number-1)%6])//左右手两边工具均为空闲状态
tools[number%6]=false;
//拿起左手工具
tools[(number-1)%6]=false;
//拿起右手工具
status=1;
LeaveCriticalSection(&
}
stringprint(Philosopher*pA)
//pA->
Change();
inti=pA->
getinfo();
stringstr;
if(i==0)
str="
等待"
;
elseif(i==1)
就餐"
elsestr="
思考"
returnstr;
stringtoolstatus(boola)
{
stringstate;
if(a==true)
state="
闲"
if(a==false)
用"
returnstate;
}
intmain()
charcon='
y'
//判断是否继续
for(inti=0;
i<
6;
i++)
tools[i]=true;
//3组刀叉都未使用,初始化
PhilosopherP1
(1),P2
(2),P3(3),P4(4),P5(5),P6(6);
InitializeCriticalSection(&
//初始化初始化临界区
cout<
<
"
-----------------------状态说明示意图:
-----------------------"
endl;
"
哲学家0号的状态"
"
哲学家5号的状态"
"
叉3的状态"
刀1的状态"
哲学家1号的状态"
"
刀3的状态"
"
叉1的状态"
哲学家4号的状态"
叉2的状态"
刀2的状态"
哲学家2号的状态"
哲学家3号的状态"
餐具的状态,“用”表示使用中,“闲”表示空闲中。
--------------------------"
哲学家们开始生活:
while(con=='
)
{
P1.Change();
P2.Change();
P3.Change();
P4.Change();
P5.Change();
P6.Change();
当前状态为:
P1.find()<
print(&
P1)<
P6.find()<
P6)<
toolstatus(tools[0])<
toolstatus(tools[1])<
P2.find()<
P2)<
toolstatus(tools[5])<
toolstatus(tools[2])<
P5.find()<
P5)<
toolstatus(tools[4])<
toolstatus(tools[3])<
P3.find()<
P3)<
P4.find()<
P4)<
若要继续下一状态,输入y;
输入其他,结束程序:
cin>
>
con;
Sleep(20);
DeleteCriticalSection(&
//退出资源区
return0;
5.测试及结果
图5-1程序运行开始界面
图5-2哲学家状态1
图5-3哲学家状态2
图5-4哲学家状态3
图5-5哲学家状态4
图5-6退出程序
6.课设总结
经过了前后共2周的时间,我完成了这次课程设计。
通过这次课程设计,我学到了许多课本上学不到的知识,注意到了许多课本上没有提到的东西。
而且,通过这次设计,我得到了一个很好的理论联系实际的机会,锻炼了通过理论解决实际问题的能力。
正所谓“实践出真知”,有些代码看上去没什么问题,但是实际运行起来就是不出正确结果。
代码内部可能存在逻辑或语法等方面我们平时不会注意到的小问题,通过这次课程设计,我积累了不少这样小问题的解决方法。
设计中总会遇到这样那样的问题,遇到问题势必要自己分析问题,通过各种渠道解决问题,比如利用互联网。
这次课程设计也加强了我上网查数检索问题的能力。
有些时候,学习到的知识是次要的,重要的是学习知识的方法。
7.参考文献
[1]宗大华,宗涛,陈吉人著.操作系统.北京:
人民邮电出版社,2009。
[2]李爱华,程磊著.面相对象程序设计(C++语言).北京:
清华大学出版社,2010。