目录1.设计题目与要求 (1)1.1实验目的与设计要求 (1)1.2 初始条件 (1)2 总体设计思想及相关知识 (2)2.1总体设计思想 (2)2.2 临界区互斥编程原理 (2)2.3开发环境与工具 (3)3数据结构与模块说明 (3)3.1 数据结构 (3)3.2程序各模块流程图 (5)3.2.1 主程序模块 (5)3.2.2 状态改变模块 (6)3.2.3 返回哲学家状态模块 (7)3.2.4 返回餐具状态模块 (8)4. 源程序代码 (9)5. 测试及结果 (14)6. 课设总结 (16)参考文献 (17)1.设计题目与要求1.1实验目的与设计要求实验目的:通过实现哲学家进餐问题的同步深入了解和掌握进程同步和互斥的原理。
设计要求:哲学家有N个,也定全体到齐后开始讨论:在讨论的间隙哲学家进餐,每人进餐时都需使用刀、叉各一把,所有哲学家刀和叉都拿到后才能进餐。
哲学家的人数、餐桌上的布置自行设定,实现刀和叉的互斥使用算法的程序实现。
1.2 初始条件(1)操作系统:windows(2)程序设计语言:C++(3)设定圆桌上有六个哲学家,三对刀叉,如下图摆放:图1-1 哲学家进餐问题设定图2 总体设计思想及相关知识2.1总体设计思想哲学家的生活就是思考和吃饭,即思考,饿了就餐,再思考,循环往复。
要:每一个哲学家只有在拿到位于他左右的刀叉后,才能够就餐;哲学家只能先拿一把刀或叉,再去拿另一把刀或叉,而不能同时去抓他旁边的两把餐具,也不能从其他哲学家手中抢夺餐具;哲学家每次就餐后必须放下他手中的两把餐具后恢复思考,不能强抓住餐具不放。
设计一个程序,能够显示当前各哲学家的状态和桌上餐具的使用情况,并能无死锁的推算出下一状态各哲学家的状态和桌上餐具的使用情况。
即设计一个能安排哲学家正常生活的程序。
为哲学家设计3种状态,即“等待”“进餐”“思考”。
每个哲学家重复进行“等待”->“进餐”->“思考”的行动循环。
其中:“等待”->“进餐”:只有一个哲学家处于等待进餐状态,且左右手两边的餐具都处于“空闲”状态时,可以发生这种状态改变。
此状态改变发生后,哲学家拿起左右手两边的餐具。
“进餐”->“思考”:此状态改变发生后,哲学家放下左右手上的餐具。
餐具状态由“使用中”转变为“空闲”。
“思考”->“等待”:哲学家思考结束后,无条件转入等待状态。
由上所述,程序中应设置6个元素的信号量数组,tools[6],用来保持哲学家之间的同步。
2.2 临界区互斥编程原理不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。
每个进程中访问临界资源的那段代码称为临界区(Critical Section)。
每个进程中访问临界资源的那段程序称为临界区(Critical Section)(临界资源是一次仅允许一个进程使用的共享资源)。
每次只准许一个进程进入临界区,进入后不允许其他进程进入。
不论是硬件临界资源,还是软件临界资源,多个进程必须互斥地对它进行访问。
本程序主要使用了EnterCriticalSection (&cs)和LeaveCriticalSection (&cs)两个函数实现临界区互斥。
EnterCriticalSection (&cs)用来进入临界区,LeaveCriticalSection (&cs)用来离开临界区。
2.3开发环境与工具系统平台:WINDOW环境实现语言:C++开发工具:VC++6.03数据结构与模块说明3.1 数据结构图3-1 哲学家类的UML图程序中定义一个哲学家类,包含两个私有对象和四个公有对象。
Number对象:报讯哲学家的编号。
Status对象:用于保存当前该哲学家的状态,0表示正在等待(即处于饥饿状态)1表示得到餐具正在吃饭,2表示正在思考Philosopher(int num)方法:哲学家类构造函数,参数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(bool a)流程图4. 源程序代码//实验目的:通过实现哲学家进餐问题的同步深入了解和掌握进程同步和互斥的原理。
//设计要求:哲学家有N个,也定全体到达后开始讨论:在讨论的间隙哲学家进餐,//每人进餐时都需使用刀、叉各一把,所有哲学家刀和叉都拿到后才能进餐。
哲学家的人数、//餐桌上的布置自行设定,实现刀和叉的互斥使用算法的程序实现。
#include <windows.h>#include <time.h>#include <string>#include <iostream>#include <assert.h>using namespace std;bool tools[6]; //全局变量,用餐工具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%6]=true; //放下左手工具tools[(number-1)%6]=true; //放下右手工具status=2; //改变状态为思考}else if(status==2) //思考中{status=0; //改变状态为等待}else if(status==0) //等待中{if(tools[number%6]&&tools[(number-1)%6]) //左右手两边工具均为空闲状态{tools[number%6]=false; //拿起左手工具tools[(number-1)%6]=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<6;i++)tools[i]=true; //3组刀叉都未使用,初始化Philosopher P1(1),P2(2),P3(3),P4(4),P5(5),P6(6);InitializeCriticalSection (&cs) ; //初始化初始化临界区cout<<"-----------------------状态说明示意图:-----------------------"<<endl;cout<<" "<<"哲学家0号的状态"<<" "<<endl;cout<<"哲学家5号的状态"<<" "<<"叉3的状态"<<" "<<"刀1的状态"<<" "<<"哲学家1号的状态"<<endl;cout<<" "<<"刀3的状态"<<" "<<"叉1的状态"<<endl;cout<<"哲学家4号的状态"<<" "<<"叉2的状态"<<" "<<"刀2的状态"<<" "<<"哲学家2号的状态"<<endl;cout<<" "<<"哲学家3号的状态"<<" "<<endl;cout<<"餐具的状态,“用”表示使用中,“闲”表示空闲中。
"<<endl;cout<<"--------------------------"<<endl;cout<<"哲学家们开始生活:"<<endl;cout<<endl;cout<<endl;while(con=='y'){P1.Change();P2.Change();P3.Change();P4.Change();P5.Change();P6.Change();cout<<"当前状态为:"<<endl;cout<<" "<<P1.find()<<print(&P1)<<" "<<endl;cout<<P6.find()<<print(&P6)<<" "<<toolstatus(tools[0])<<""<<toolstatus(tools[1])<<" "<<P2.find()<<print(&P2)<<endl;cout<<" "<<toolstatus(tools[5])<<""<<toolstatus(tools[2])<<endl;cout<<P5.find()<<print(&P5)<<" "<<toolstatus(tools[4])<<""<<toolstatus(tools[3])<<" "<<P3.find()<<print(&P3)<<endl;cout<<" "<<P4.find()<<print(&P4)<<" "<<endl;cout<<"--------------------------"<<endl;cout<<"若要继续下一状态,输入y;输入其他,结束程序:";cin>>con;Sleep(20);}DeleteCriticalSection (&cs) ; //退出资源区return 0;}5. 测试及结果图5-1 程序运行开始界面图5-2 哲学家状态1图5-3 哲学家状态2图5-4 哲学家状态3图5-5 哲学家状态4图5-6 退出程序6. 课设总结经过了前后共2周的时间,我完成了这次课程设计。