操作系统课程设计 哲学家进餐问题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
哲学家进餐问题课程设计
哲学家进餐问题设计说明书(或论文)
(封面)
学院名称:计算机信息与工程学院
班级名称: 2012级计算机科学与技术
学生姓名:操飞飞
学号: 2012211296 题目:哲学家进餐问题
指导教师
姓名:马丽生
起止日期:2014年6月3日至2014年6月30日
目录
第一部分:正文部分 (1)
一、选题背景 (1)
二、设计思路 (1)
(1)总体设计思想 (1)
(2)资源互斥问题 (1)
三、过程论述 (2)
(1)数据结构 (2)
(2)程序模块 (3)
四、结果分析 (6)
(1)程序开始执行状态 (6)
(2)哲家状态图 (6)
(3)程序结束图 (8)
五、结论(或总结) (9)
第二部分:参考文献 (9)
第三部分:指导教师评语 (10)
第四部分:成绩评定 (10)
附录 (11)
第一部分:正文部分
一、选题背景
哲学家进餐问题
由Dijkstra提出并解决的哲学家进餐问题(The Dinning Philosophers Problem)是典型的同步问题,该问题是描述有五个哲学家共用一张圆桌,分别坐在周围的五张椅子上,在圆桌上有五个碗和五只筷子,他们的生活方式是交替地进行思考和进餐,平时,一个哲学家进行思考,饥饿时便试图取用其左右最靠近他的筷子,只有在他拿到两只筷子时才能进餐,进餐毕,放下筷子继续思考.
此次课程设计的主要内容是模拟实现资源分配。
同时要求编写和调试一个系统动态分配资源的简单模拟程序,观察死锁产生的条件,设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上餐具的使用情况。
二、设计思路
(1)总体设计思想
为哲学家设计3种状态,即“等待”“进餐”“思考”。
每个哲学家重复进行“等待”->“进餐”->“思考”的行动循环。
其中:
“等待”->“进餐”:只有一个哲学家处于等待进餐状态,且左右手两边的餐具都处于“空闲”状态时,可以发生这种状态改变。
此状态改变发生后,哲学家拿起左右手两边的餐具。
“进餐”->“思考”:此状态改变发生后,哲学家放下左右手上的餐具。
餐具状态由“使用中”转变为“空闲”。
“思考”->“等待”:哲学家思考结束后,无条件转入等待状态。
设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上餐具的使用情况。
即设计一个能安排哲学家正常生活的程序。
(2)资源互斥问题
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。
每个进程中访问临界资源的那段代码称为临界区(Critical Section)。
每个进程中访问临界资源的那段程序称为临界区(Critical Section)(临界资源是一次仅允许一个进程使用的共享资源)。
每次只准许一个进程进入临界区,进入后不允许其他进程进入。
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问
本程序主要使用了EnterCriticalSection (&cs)和LeaveCriticalSection (&cs)两个函数实现临界区互斥。
EnterCriticalSection (&cs)用来进入临界区,LeaveCriticalSection (&cs)用来离开临界区。
三、过程论述
(1)数据结构
① class Philosopher:定义一个哲学家类,包含两个私有对象和四个公有对象。
② int number,int status:用于记录哲学家编号以及用于保存当前该哲学家的状态,0表示正在等待(即处于饥饿状态)1表示得到餐具正在吃饭,2表示正在思考。
③ Philosopher(int num)方法:哲学家类构造函数,参数num表示哲学家编号。
④ find() const方法:返回该哲学家编号。
⑤ getinfo() const方法:返回哲学家当前状态。
⑥ Change()方法:根据题目要求改变哲学家的状态(等待->进餐->思考->等待…………)
⑦ bool tools[5]:bool类型数组tools[6],用来保存6把餐当前状态:true 表示该餐具当前空闲,false表示该餐具当前正被使用。
⑧ Print:Print用来返回一个哲学家的状态。
⑨ toolstatus:toolstatus用来返回一个餐具的状态。
⑩ EnterCriticalSection(&cs)和LeaveCriticalSection (&cs):用来进入临界区及用来离开临界区。
(2)程序模块
①主程序模块
图3.1主程序模块②状态改变模块
图3.2状态改变程序模块
③返回哲学家状态模块
图3.3哲学家状态模块④返回餐具状态模块
图3.4餐具状态模块
四、结果分析
(1)程序开始执行状态
图4.1程序开始执行状态(2)哲家状态图
图4.2哲学家的状态图1
图4.3哲学家状态图2 图4.4哲学家状态图3
图4.5哲学家状态图4(3)程序结束图
图4.6程序结束图
五、结论(或总结)
经过4周的时间完成了这次的课程设计,通过这次课程设计,我解决了哲学家进餐问题,加深了windows平台下信号量的理解,了解死锁的产生以及死锁的解决方法。
而且,通过这次设计,我学到了许多课本上学不到的知识,注意到了许多课本上没有提到的东西,我得到了一个很好的理论联系实际的机会,锻炼了通过理论解决实际问题的能力。
正所谓“实践出真知”,有些代码看上去没什么问题,但是实际运行起来就是不出正确结果。
代码内部可能存在逻辑或语法等方面我们平时不会注意到的小问题,通过这次课程设计,我积累了不少这样小问题的解决方法。
设计中总会遇到这样那样的问题,遇到问题势必要自己分析问题,通过各种渠道解决问题,比如利用互联网。
这次课程设计也加强了我上网查数检索问题的能力。
有些时候,学习到的知识是次要的,重要的是学习知识的方法。
第二部分:参考文献
1.汤小丹,计算机操作系统[第三版],西安电子科技出版社,2007;
2.黄干平,陈洛资,等.计算机操作系统.北京:科学出版社,1989;
3.李勇,陈恩林.计算机体系结构.长沙:国防科技大学出版,1987;
4.黄祥喜,计算机操作系统实验教程.广州:中山大学出版社,1994.
学生签名:操飞飞填表日期:2014年6月15日
第三部分:指导教师评语
第四部分:成绩评定
指导教师签名:填表日期:年月日
附录
#include <windows.h>
#include <time.h>
#include <string>
#include <iostream>
#include <assert.h>
using namespace std; //控制活动线程数目的信号量(保护线程共享资源)bool tools[5]; //全局变量,用餐工具
CRITICAL_SECTION cs; //信号量, 在线程中使用,临界区
class Philosopher
{
private:
int number;
int status; /*标记当前哲学家的状态,0表示正在等待(即处于饥饿状态),1表示得到两支筷子正在吃饭,2表示正在思考*/
public:
Philosopher(int num=0): status(2), number(num) { }
int find() const { return number; }
int getinfo() const { return status; }
void Change() ; //状态改变函数
};
void Philosopher::Change()
{
EnterCriticalSection (&cs) ; //进入临界区
if(status==1) //正在进餐
{
tools[number%5]=true; //放下左手工具
tools[(number+1)%5]=true; //放下右手工具
status=2; //改变状态为思考
}
else if(status==2) //思考中
{
status=0; //改变状态为等待
}
else if(status==0) //等待中
{
if(tools[number%5]&&tools[(number+1)%5]) //左右手两边工具均为空闲状态
{
tools[number%5]=false; //拿起左手工具
tools[(number+1)%5]=false; //拿起右手工具
status=1;
}
}
LeaveCriticalSection (&cs) ;
}
string print(Philosopher *pA)
{
//pA->Change();
int i=pA->getinfo();
string str;
if(i==0)
str="等待";
else if(i==1)
str="就餐";
else str="思考";
return str;
}
string toolstatus(bool a)
{
string state;
if(a==true)
state="闲";
if(a==false)
state="用";
return state;
}
int main()
{
char con = 'y'; //判断是否继续
for(int i=0;i<5;i++)
tools[i]=true;
Philosopher P1(1),P2(2),P3(3),P4(4),P5(5);
InitializeCriticalSection (&cs) ; //初始化初始化临界区
cout<<"-----------------------状态说明示意图:
-----------------------"<<endl;
cout<<" "<<"哲学家1号的状态"<<" "<<endl;
cout<<" "<<"筷5的状态"<<" "<<"筷1的状态"<<endl;
cout<<"哲学家5号的状态"<<" "<<"哲学家2号的
状态"<<endl;
cout<<" "<<"筷4的状态"<<" "<<"筷2的
状态"<<endl;
cout<<"哲学家4号的状态"<<" "<<"筷3的状态"<<" "<<"哲学家3号的状态"<<endl;
cout<<"--------------------------"<<endl;
cout<<"哲学家们开始生活:"<<endl;
cout<<endl;
cout<<endl;
while(con=='y')
{
P1.Change();
P2.Change();
P3.Change();
P4.Change();
P5.Change();
cout<<"当前状态为:"<<endl;
cout<<" "<<P1.find()<<print(&P1)<<" "<<endl;
cout<<" "<<toolstatus(tools[1])<<"
"<<toolstatus(tools[2])<<endl;
cout<<P5.find()<<print(&P5)<<"
"<<P2.find()<<print(&P2)<<endl;
cout<<" "<<toolstatus(tools[0])<<"
"<<toolstatus(tools[3])<<endl;
cout<<P4.find()<<print(&P4)<<"
"<<toolstatus(tools[4])<<" "<<P3.find()<<print(&P3)<<endl;
cout<<"--------------------------"<<endl;
cout<<"若要继续下一状态,输入y;输入其他,结束程序:";
cin>>con;
Sleep(20);
}
DeleteCriticalSection (&cs) ; //退出资源区
return 0; }。