// Test.cpp : Defines the entry point for the console application.//#include "stdafx.h"#includeusing namespace std;#define LEFT(n) ((n+4)%5)#define RIGHT(n) ((n+1)%5)class MySemaphore{public: MySemaphore::MySemaphore(long nInitCount) { m_sem = CreateSemaphore(NULL,nInitCount,MAXLONG32,NULL); } bool down(DWORD dwMilliseconds) { if (m_sem) { DWORD dwRet = WaitForSingleObject(m_sem,dwMilliseconds); if (WAIT_OBJECT_0 == dwRet) { return true; } } return false; } bool up() { if (m_sem) { return ReleaseSemaphore(m_sem,1,NULL) ? true : false; } return false; }private: HANDLE m_sem;};enum PersonState{ STATE_THINKING, STATE_WAITING, STATE_EATING,};MySemaphore personArr[5] = {0,0,0,0,0};PersonState stateArr[5] = {STATE_THINKING,STATE_THINKING,STATE_THINKING,STATE_THINKING,STATE_THINKING};MySemaphore mutex = 1;void test(int nIndex){ if (stateArr[nIndex] == STATE_WAITING && stateArr[LEFT(nIndex)] != STATE_EATING&& stateArr[RIGHT(nIndex)] != STATE_EATING) { stateArr[nIndex] = STATE_EATING; personArr[nIndex].up(); }}void take_fork(int nIndex){ mutex.down(INFINITE); stateArr[nIndex] = STATE_WAITING; test(nIndex); mutex.up(); personArr[nIndex].down(INFINITE);}void put_fork(int nIndex){ mutex.down(INFINITE); stateArr[nIndex] = STATE_THINKING; printf("person %d put fork and thinking\n",nIndex+1); test(LEFT(nIndex)); test(RIGHT(nIndex)); mutex.up();}DWORD WINAPI PersonProc( LPVOID lpParam ){ int nThreadIndex = (int)lpParam; for(;;) { take_fork(nThreadIndex); printf("person %d take fork and eating\n",nThreadIndex+1); Sleep(1000); //eating; put_fork(nThreadIndex); } return 0;}int _tmain(int argc, _TCHAR* argv[]){ HANDLE aThread[5]; for(int i=0; i < 5; i++ ) { aThread[i] = CreateThread( NULL, // default security attributes 0, // default stack size (LPTHREAD_START_ROUTINE) PersonProc, (void*)i, // no thread function arguments 0, // default creation flags NULL); // receive thread identifier if( aThread[i] == NULL ) { printf("CreateThread error: %d\n", GetLastError()); return 1; } } Sleep(-1); return 0;}
详细分析參考<现代操作系统>相关章节