算法的具体实现

具体代码如下：
toc code /***********************semaphore.h***************************** Semaphore类用于模拟信号量 用法如:Semaphore sem(1); (1)要求初始信号量值非负 (2)信号量P操作： sem.P; (3)信号量V操作： sem.V;



class Semaphore{ protected: HANDLE sem; public: //Semaphore; //void SetValve(int SemValue); Semaphore(unsigned int SemValue); virtual ~Semaphore; void P; void V; };
 * 1) ifndef SEMAPHORE_H
 * 2) define SEMAPHORE_H
 * 3) include 


 * 1) endif

code

申明过后是定义文件：
code /*****************************semaphore.cpp************************************/
 * 1) include 
 * 2) include 
 * 3) include 
 * 4) 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); }

code

然后是线程头文件
code /*****************************thread.h*************************************

通过startThread开启线程 startThread(PTHREAD_START func,void * param); 用法： //定义一个PTHREAD_START类型的函数func unsigned int WINAPI func (void * param){ //... return 0; } //启动一个线程使其执行func函数 startThread(func,NULL);



/* 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 *);
 * 1) ifndef THREAD_H
 * 2) define THREAD_H
 * 3) include 
 * 4) include 

/* chBEGINTHREADEX is From 

pvParam, dwCreateFlags, pdwThreadId)                \ ((HANDLE)_beginthreadex(                          \ (void *)        (psa),                         \ (unsigned)      (cbStackSize),                 \ (PTHREAD_START) (pfnStartAddr),                \ (void *)        (pvParam),                     \ (unsigned)      (dwCreateFlags),               \ (unsigned *)    (pdwThreadId))) // rename chBEGINTHREADEX to startThread for simplicity chBEGINTHREADEX(NULL, 0, (pfnStartAddr),(pvParam), 0, NULL)
 * 1) define chBEGINTHREADEX(psa, cbStackSize, pfnStartAddr, \
 * 1) define chBEGINTHREADEX(psa, cbStackSize, pfnStartAddr, \
 * 1) define startThread(pfnStartAddr,pvParam)\


 * 1) endif

code

最后是驱动程序
code /*****************************main函数（主函数）************************************/ 假设偶数号哲学家先拿左边的筷子，右边的哲学家先拿起右边的筷子.
 * 1) include 
 * 2) include "semaphore.h"
 * 3) include "thread.h"
 * 4) include 
 * 5) include 
 * 6) define N  6                                            //哲学家的个数
 * 7) define LEFT(i)    (i+N-1)%N                            //左边的筷子
 * 8) define RIGHT(i)   (i==N-1)?0:(i+N)%N                   //右边的筷子 编号为N的哲学家的右边的筷子编号为0

/*******************************初始化信号量**************************************/ Semaphore ChopStick[N]={Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(1),Semaphore(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<N;Philosopher_id++) { CloseHandle(hPhilosopher[Philosopher_id]); }

return 0; }

code