HANDLE Mutex; // 互斥信号量 HANDLE ChopStick[6]; // 筷子信号量 BOOL ChopstickUsed[6]; // 筷子已被其它线程申请并保持 DWORD PhilosopherID[6]; // 哲学家线程标识符 HANDLE tPhilosopher[6]; // 哲学家线程句柄 RECT PRect[6] = {{350, 100, 380, 130}, {650, 100, 680, 130}, {800, 310, 830, 340},
{650, 520, 680, 550}, {350, 520, 380, 550}, {200, 310, 230, 340}};
HBRUSH hBrush[7]; // 红、绿、蓝、黄、白色刷子
POINT CPolygon[6][4] = {{{210, 177}, {290, 217}, {284, 226}, {204, 186}}, {{510, 50}, {520, 50}, {520, 130}, {510, 130}}, {{724, 217}, {804, 177}, {810, 185}, {730, 225}}, {{730, 427}, {810, 467}, {804, 476}, {724, 436}}, {{510, 520}, {520, 520}, {520, 600}, {510, 600}}, {{204, 467}, {284, 427}, {290, 435}, {210, 475}}};
DWORD FAR PASCAL Philosopher(LPVOID); // 哲学家线程 void Wait(HANDLE); // 等待信号量 void Signal(HANDLE); // 发送信号量 void DrawChopstick(HBRUSH, int, BOOL); // 用对应颜色刷子画筷子
// 并设置/取消使用标记
void WaitTime(int);
//--------------------------------------------------------------------------- // DWORD FAR PASCAL InitThreadSemaphore() //
// Description:
// 生成哲学家线程及各种信号量和变量初始化 //
//--------------------------------------------------------------------------- void InitThreadSemaphore() { int i; hBrush[0] = CreateSolidBrush(RGB(255, 0, 0 )); hBrush[1] = CreateSolidBrush(RGB( 0, 255, 0 )); hBrush[2] = CreateSolidBrush(RGB( 0, 0, 255)); hBrush[3] = CreateSolidBrush(RGB(255, 255, 0 )); hBrush[4] = CreateSolidBrush(RGB( 0, 255, 255)); hBrush[5] = CreateSolidBrush(RGB(255, 0, 255)); hBrush[6] = CreateSolidBrush(RGB(255, 255, 255)); DrawPhilosopher();
-6-
// 红色刷子 // 绿色刷子 // 蓝色刷子 // 黄色刷子 // 青色刷子 // 棕色刷子 // 白色刷子
for (i=0; i<6; i++) ChopStick[i] = CreateSemaphore(NULL, 1, 1, NULL); // 生成筷子信号量 Mutex = CreateSemaphore(NULL, 1, 1, NULL); // 生成互斥信号量--画筷子或判断筷子是否被申请 for (i=0; i<6; i++) ChopstickUsed[i] = FALSE; // 筷子未被其它线程申请并保持 tPhilosopher[0] = CreateThread((LPSECURITY_ATTRIBUTES) NULL, // 生成哲学家0线程 0, (LPTHREAD_START_ROUTINE) Philosopher, \ 0, &PhilosopherID[0]); tPhilosopher[1] = CreateThread((LPSECURITY_ATTRIBUTES) NULL, // 生成哲学家1线程 0, (LPTHREAD_START_ROUTINE) Philosopher, \ 0, &PhilosopherID[1]); tPhilosopher[2] = CreateThread((LPSECURITY_ATTRIBUTES) NULL, // 生成哲学家2线程 0, (LPTHREAD_START_ROUTINE) Philosopher, \ 0, &PhilosopherID[2]); tPhilosopher[3] = CreateThread((LPSECURITY_ATTRIBUTES) NULL, // 生成哲学家3线程 0, (LPTHREAD_START_ROUTINE) Philosopher, \ 0, &PhilosopherID[3]); tPhilosopher[4] = CreateThread((LPSECURITY_ATTRIBUTES) NULL, // 生成哲学家4线程 0, (LPTHREAD_START_ROUTINE) Philosopher, \ 0, &PhilosopherID[4]); tPhilosopher[5] = CreateThread((LPSECURITY_ATTRIBUTES) NULL, // 生成哲学家5线程 0, (LPTHREAD_START_ROUTINE) Philosopher, \ 0, &PhilosopherID[5]); }
void DrawPhilosopher(void) { int i; SelectObject(hWDC, hBrush[6]); for (i=0; i<6; i++) Polygon(hWDC, CPolygon[i], 4); for (i=0; i<6; i++) {
-7-
SelectObject(hWDC, hBrush[i]); Ellipse(hWDC, PRect[i].left, PRect[i].top, PRect[i].right, PRect[i].bottom); } }
//--------------------------------------------------------------------------- // DWORD FAR PASCAL Philosopher1() //
// Description:
// 哲学家线程----线程同步及预防死锁 //
//--------------------------------------------------------------------------- DWORD FAR PASCAL Philosopher(LPVOID ThreadParaStr) { int Loop, ThreadID; int R1, R2; ThreadID = atoi((char *) ThreadParaStr); Loop = 0; while (TRUE) { R1 = ThreadID; R2 = (ThreadID+1) % 6; /* // 摒弃‘环路等待’条件 if (ThreadID == 0) { R1 = (ThreadID+1) % 6; R2 = ThreadID; } */ /* // 摒弃‘请求和保持’条件 Wait(Mutex); if ((ChopstickUsed[R1]) || (ChopstickUsed[R2])) { Signal(Mutex); goto LoopAgain; } Signal(Mutex); */ Wait(ChopStick[R1]); DrawChopstick(hBrush[ThreadID], R1, TRUE); /*
-8-
// 拿到左手筷子 // 将筷子画上颜色并设置使用标志 // 摒弃‘不剥夺’条件 Wait(Mutex); if (ChopstickUsed[R2]) { Signal(Mutex); goto ReleaseChopstick; } Signal(Mutex); */ Wait(ChopStick[R2]); // 拿到右手筷子 DrawChopstick(hBrush[ThreadID], R2, TRUE); // 将筷子画上颜色并设置使用标志 WaitTime(1000*((Loop*ThreadID%5)+1)); // 吃饭 DrawChopstick(hBrush[6], R2, FALSE); // 去掉筷子颜色并取消筷子已使用标志 Signal(ChopStick[R2]);
ReleaseChopstick: DrawChopstick(hBrush[6], R1, FALSE); // 去掉筷子颜色并取消筷子已使用标志 Signal(ChopStick[R1]);
LoopAgain: WaitTime(2000*(Loop%7+1)); // 思考 if (Loop++>10000) Loop = 0; } return(0); }
//--------------------------------------------------------------------------- // DWORD FAR PASCAL Philosopher4() //
// Description: // 画筷子线程 //
//---------------------------------------------------------------------------
void DrawChopstick(HBRUSH hChopstickBrush, int ChopstickID, BOOL ChopstickUsedID) { Wait(Mutex); if (ChopstickUsedID) { ChopstickUsed[ChopstickID] = TRUE; // 设置筷子已使用标志 SelectObject(hWDC, hChopstickBrush); Polygon(hWDC, CPolygon[ChopstickID], 4); } else {
-9-
ChopstickUsed[ChopstickID] = FALSE; // 取消筷子已使用标志
SelectObject(hWDC, hChopstickBrush); Polygon(hWDC, CPolygon[ChopstickID], 4); } Signal(Mutex); }
//--------------------------------------------------------------------------- // void WaitTime() //
// Description:
// 延迟器(单位ms) //
//--------------------------------------------------------------------------- void WaitTime(int msTime) { int i; double Area, PI, r; PI = 3.14159; r = 10.12345; for (i=0; i<300 * msTime; i++) Area = PI * r * r; }
void Wait(HANDLE hSemaphore) { WaitForSingleObject(hSemaphore, INFINITE); }
void Signal(HANDLE hSemaphore) { ReleaseSemaphore(hSemaphore, 1, NULL); }
-10-
// 等待信号量
// 发送信号量