为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

哲学家进餐问题

2017-10-08 8页 doc 36KB 75阅读

用户头像

is_682974

暂无简介

举报
哲学家进餐问题哲学家进餐问题 学家就餐问题 C++ P V原语实现 哲学家就餐问题是一种典型的同步问题,它是由Dijkstra 提出并解决的。该问题描述 :有五个哲学家,他们的生活方式是交替的进行思考和进餐。哲学家们共用一张圆桌, 设五个哲学家分别编号为A,B,C,D,E,桌子上放着五把筷子,筷子分别编号为 0,1, 2,3,4,桌子中央有一盘饭菜。五个哲学家都很有礼貌,都要等同时拿到身旁的两只筷子 才进餐,不然就只是等着继续思考,而且吃了一口之后又马上放下拿起的两根筷子,继续思 考。 用P V原语的方式实现 每个哲学家...
哲学家进餐问题
哲学家进餐问题 学家就餐问题 C++ P V原语实现 哲学家就餐问题是一种典型的同步问题,它是由Dijkstra 提出并解决的。该问题描述 :有五个哲学家,他们的生活方式是交替的进行思考和进餐。哲学家们共用一张圆桌, 设五个哲学家分别编号为A,B,C,D,E,桌子上放着五把筷子,筷子分别编号为 0,1, 2,3,4,桌子中央有一盘饭菜。五个哲学家都很有礼貌,都要等同时拿到身旁的两只筷子 才进餐,不然就只是等着继续思考,而且吃了一口之后又马上放下拿起的两根筷子,继续思 考。 用P V原语的方式实现 每个哲学家可用一个线程来模拟,信号量及其P、V操作的实现 定义一个semaphore 类 封装 P V原语模拟函数 (不妨设有6个哲学家,6只筷子, 每只筷子各对应一个信号量且每个信号量初始值应为1) /***********************semaphore.h***************************** Semaphore类用于模拟信号量 用法如:Semaphore sem(1); (1)要求初始信号量值非负 (2)信号量P操作: sem.P(); (3)信号量V操作: sem.V(); ****************************************************/ #ifndef SEMAPHORE_H #define SEMAPHORE_H #include class Semaphore{ protected: HANDLE sem; public: //Semaphore(); //void SetValve(int SemValue); Semaphore(unsigned int SemValue); virtual ~Semaphore(); void P(); void V(); }; #endif /*****************************semaphore.cpp************************************/ #include #include #include #include "semaphore.h" Semaphore::Semaphore(unsigned int semValue){ if(semValue > LONG_MAX) semValue = LONG_MAX; sem = CreateSemaphore(NULL,semValue,LONG_MAX,NULL); } Semaphore::~Semaphore(){ CloseHandle(sem); } void Semaphore::P(){ DWORD dw = WaitForSingleObject(sem, INFINITE); assert(dw == WAIT_OBJECT_0); } void Semaphore::V(){ ReleaseSemaphore(sem,1,NULL); } /*****************************thread.h************************************* 通过startThread开启线程 startThread(PTHREAD_START func,void * param); 用法: //定义一个PTHREAD_START类型的函数func unsigned int WINAPI func (void * param){ //... return 0; } //启动一个线程使其执行func函数 startThread(func,NULL); ********************************************************************/ #ifndef THREAD_H #define THREAD_H #include #include /* from MSDN : Start address of a routine that begins execution of a new thread. For _beginthread, the calling convention is either __cdecl or __clrcall; for _beginthreadex, it is either __stdcall or __clrcall. WINAPI即为__stdcall */ typedef unsigned int (WINAPI *PTHREAD_START) (void *); /* chBEGINTHREADEX is From */ #define chBEGINTHREADEX(psa, cbStackSize, pfnStartAddr, \ pvParam, dwCreateFlags, pdwThreadId) \ ((HANDLE)_beginthreadex( \ (void *) (psa), \ (unsigned) (cbStackSize), \ (PTHREAD_START) (pfnStartAddr), \ (void *) (pvParam), \ (unsigned) (dwCreateFlags), \ (unsigned *) (pdwThreadId))) // rename chBEGINTHREADEX to startThread for simplicity #define startThread(pfnStartAddr,pvParam)\ chBEGINTHREADEX(NULL, 0, (pfnStartAddr),(pvParam), 0, NULL) #endif /*****************************main函数(主函数)************************************/ 假设偶数号哲学家先拿左边的筷子,右边的哲学家先拿起右边的筷子。 #include #include "semaphore.h" #include "thread.h" #include #include #define N 6 //哲学家的个数 #define LEFT(i) (i+N-1)%N //左边的筷子 #define RIGHT(i) (i==N-1)?0:(i+N)%N //右边的筷子 编号为N的哲 学家的右边的筷子编号为0 /*******************************初始化信号量**************************************/ Semaphore ChopStick[N]={Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1),Sema phore(1),Semaphore(1)} ; /*******************************哲学家状态*******************************************/ void Eating(int Ph_Id) { printf("Philosopher%d: \tI'm eating......\t",(int)Ph_Id); } void Sleeping(int Ph_Id) { printf("Philosopher%d:\tI'm sleeping......\t",(int)Ph_Id); Sleep(rand()%10000); } void Thinking(int Ph_Id) { printf("Philosopher%d: \tI'm thinking......\t",(int)Ph_Id); } /********************************************************************/ void Philosopher(int pid){ while (true) { if (pid%2 == 0) //偶数号哲学家 { Thinking(pid); //等待中 ChopStick[LEFT(pid)].P(); //先拿起左边的筷子,再拿起右边的筷子 ChopStick[RIGHT(pid)].P(); Eating(pid); //获得的两个信号量则eating ChopStick[LEFT(pid)].V(); //先后释放左右信号量 ChopStick[RIGHT(pid)].V(); printf("\n"); } else if(pid%2==1 ) //奇数号哲学家 { Thinking(pid); ChopStick[RIGHT(pid)].P(); //先拿起右边的筷子,再拿起左边的筷子 ChopStick[LEFT(pid)].P(); Eating(pid); //左右都得到筷子后则eating ChopStick[RIGHT(pid)].V(); //先后释放右左信号量 ChopStick[LEFT(pid)].V(); printf("\n"); } Sleeping(pid); //吃完睡上一会儿 } } int main(){ HANDLE hPhilosopher[N]; //为每个哲学家分配一个线程 int count =0 ; for (int Philosopher_id =0 ;Philosopher_id5) break; } ::WaitForMultipleObjects(N,hPhilosopher,TRUE,INFINITE); for (Philosopher_id = 0 ; Philosopher_id
/
本文档为【哲学家进餐问题】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索