您好,欢迎来到化拓教育网。
搜索
您的当前位置:首页哲学家就餐问题

哲学家就餐问题

来源:化拓教育网


课程设计报告

哲学家就餐问题

学 院 专 业

学 号 学 生 姓 名 指导教师姓名

2012年3月 14日

1.实验目的与设计要求

实验目的:通过实现哲学家进餐问题的同步深入了解和掌握进程同步和互斥的原理。

设计要求:哲学家有N个,也定全体到齐后开始讨论:在讨论的间隙哲学家进餐,每人进餐时都需使用两双筷子,所有哲学家两双筷子都拿到后才能进餐。哲学家的人数、餐桌上的布置自行设定,实现筷子互斥使用算法的程序实现。

2.总体设计思想

哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复。要求是:每一个哲学家只有在拿到位于他左右的筷子后,才能够就餐;哲学家只能先拿一个筷子,再去拿另一个筷子,而不能同时去抓他旁边的两把餐具,也不能从其他哲学家手中抢夺餐具;哲学家每次就餐后必须放下他手中的两把餐具后恢复思考,不能强抓住餐具不放。

设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上餐具的使用情况。即设计一个能安排哲学家正常生活的程序。

为哲学家设计3种状态,即“等待”“进餐”“思考”。每个哲学家重复进行“等待”->“进餐”->“思考”的行动循环。其中:

“等待”->“进餐”:只有一个哲学家处于等待进餐状态,且左右手两边的餐具都处于“空闲”状态时,可以发生这种状态改变。此状态改变发生后,哲学家拿起左右手两边的餐具。

“进餐”->“思考”:此状态改变发生后,哲学家放下左右手上的餐具。餐具状态由“使用中”转变为“空闲”。

“思考”->“等待”:哲学家思考结束后,无条件转入等待状态。 由上所述,程序中应设置6个元素的信号量数组,tools[6],用来保持哲学家之间的同步。

程序中定义一个哲学家类,包含两个私有对象和四个公有对象。 Number对象:哲学家的编号。

Status对象:用于保存当前该哲学家的状态,0表示正在等待(即处于饥饿状态)

1表示得到餐具正在吃饭,2表示正在思考

Philosopher(int num)方法:哲学家类构造函数,参数num表示哲学家编号 find() const方法:返回该哲学家编号 getinfo() const方法:返回哲学家当前状态

Change()方法:根据题目要求改变哲学家的状态(等待->进餐->思考->等

待„„„„)

另外,程序中包含一个公有对象,bool类型数组tools[5],用来保存5个筷子当前状态:true表示该餐具当前空闲,false表示该餐具当前正被使用。

程序中还包含两个公有函数:print和toolstatus。Print用来返回一个哲学家的状态,toolstatus用来返回一个餐具的状态。

3.程序各模块流程图 3. 1 主程序模块

开始 定义信号量tools[5] 定义哲学家类对象P1-P5 哲学家的状态发生改变;P1.change();P2.change();P3.change();P4.change();P5.change() 输出当前状态 停止程序 否 结束

3.2 状态改变模块

开始 哲学家处于的状态status==1 是 放下左右手工具 否 哲学家处于思考状态 Status==2 否 哲学家处于等待 Status==0 状态为思考 Status==2 是状态改为等待status==0 是 左右手筷子均空闲 是 拿起左右手筷子 状态改为就餐status==1 结束

3.3 返回哲学家状态模块

3.4 返回餐具状态模块

4. 源程序代码

#include #include #include #include #include

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) { } const int find() { return number; }

const int getinfo()

{ return status; }

void Change() ; //状态改变函数 void dead_lock(); };

/////////

void Philosopher::dead_lock() {

EnterCriticalSection (&cs) ; //进入临界区 string s; if(status==1)

{ tools[number%5]=true; // tools[(number-1)%5]=true; status=2; }

else if(status==2) { status=0; //tools[(number-1)%5]=false; //tools[(number-1)%5]=true; }

else if(status==0) { tools[number%5]=false; tools[(number-1)%5]=false; status=1; }

LeaveCriticalSection (&cs) ; // cout<<\"*********\"; }

/////////

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'; //判断是否继续 // con = 'n';

for(int i=0;i<5;i++)

tools[i]=true; //筷子都未使用,初始化

Philosopher P1(1),P2(2),P3(3),P4(4),P5(5);

InitializeCriticalSection (&cs) ; //初始化初始化临界区

cout<<\"-----------------------状态说明示意图:-----------------------\"<cout<<\"哲学家5号的状态\"<<\" \"<<\"哲学家2号的状态\"<cout<<\"筷子的状态,用表示使用中,闲表示空闲中。\"<//cout<<\"当前状态:\"; cout<>con;

while(con=='y') {

P1.Change(); P2.Change(); P3.Change(); P4.Change(); P5.Change(); cout<<\"当前状态为:\"<cout<<\" \"<cout<<\" \"<cout<<\" \"<cout<<\"若要继续下一状态,输入y;输入n进入死锁;输入其他,结束程序:\"; cin>>con; Sleep(20); }

while(con=='n') { P1.dead_lock(); P2.dead_lock(); P3.dead_lock(); P4.dead_lock(); P5.dead_lock(); cout<<\"死锁情况\"<cout<<\" \"<cout<<\" \"<cout<<\"输入n继续;输入其他,结束程序:\"; cin>>con; Sleep(20); }

DeleteCriticalSection (&cs) ; //退出资源区

return 0; }

5. 测试及结果

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo9.cn 版权所有 赣ICP备2023008801号-1

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务