如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
学家就餐问题C++PV原语实现哲学家就餐问题是一种典型的同步问题,它是由Dijkstra提出并解决的。该问题描述:有五个哲学家,他们的生活方式是交替的进行思考和进餐。哲学家们共用一张圆桌,设五个哲学家分别编号为A,B,C,D,E,桌子上放着五把筷子,筷子分别编号为0,1,2,3,4,桌子中央有一盘饭菜。五个哲学家都很有礼貌,都要等同时拿到身旁的两只筷子才进餐,不然就只是等着继续思考,而且吃了一口之后又马上放下拿起的两根筷子,继续思考。用PV原语的方式实现每个哲学家可用一个线程来模拟,信号量及其P、V操作的实现定义一个semaphore类封装PV原语模拟函数(不妨设有6个哲学家,6只筷子,每只筷子各对应一个信号量且每个信号量初始值应为1)/***********************semaphore.h*****************************Semaphore类用于模拟信号量用法如:Semaphoresem(1);(1)要求初始信号量值非负(2)信号量P操作:sem.P();(3)信号量V操作:sem.V();****************************************************/#ifndefSEMAPHORE_H#defineSEMAPHORE_H#include<windows.h>classSemaphore{protected:HANDLEsem;public://Semaphore();//voidSetValve(intSemValue);Semaphore(unsignedintSemValue);virtual~Semaphore();voidP();voidV();};#endif/*****************************semaphore.cpp************************************/#include<windows.h>#include<LIMITS.H>#include<assert.h>#include"semaphore.h"Semaphore::Semaphore(unsignedintsemValue){if(semValue>LONG_MAX)semValue=LONG_MAX;sem=CreateSemaphore(NULL,semValue,LONG_MAX,NULL);}Semaphore::~Semaphore(){CloseHandle(sem);}voidSemaphore::P(){DWORDdw=WaitForSingleObject(sem,INFINITE);assert(dw==WAIT_OBJECT_0);}voidSemaphore::V(){ReleaseSemaphore(sem,1,NULL);}/*****************************thread.h*************************************通过startThread开启线程startThread(PTHREAD_STARTfunc,void*param);用法://定义一个PTHREAD_START类型的函数funcunsignedintWINAPIfunc(void*param){//...return0;}//启动一个线程使其执行func函数startThread(func,NULL);********************************************************************/#ifndefTHREAD_H#defineTHREAD_H#include<windows.h>#include<process.h>/*fromMSDN:Startaddressofaroutinethatbeginsexecutionofanewthread.For_beginthread,thecallingconventioniseither__cdeclor__clrcall;for_beginthreadex,itiseither__stdcallor__clrcall.WINAPI即为__stdcall*/typedefunsignedint(WINAPI*PTHREAD_START)(void*);/*chBEGINTHREADEXisFrom<WindowsViaC&C++>*/#definechBEGINTHREADEX(psa,cbStackSize,pfnStartAddr,\pvParam,dwCreateFlags,pdwThreadId)\((HANDLE)_beginthreadex(