?? mutex.c
字號:
/*
* Mutex.c
*
* Sample code for "Multithreading Applications in Win32"
* This sample is discussed in Chapter 4.
*
* Graphically demonstrates the problem of the
* dining philosophers.
*
* This version uses mutexes with WaitForSingleObject(),
* which can cause deadlock, and WaitForMultipleObjects(),
* which always works properly.
*/
#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include "MtVerify.h"
#include "dining.h"
int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
BOOL InitApplication(HINSTANCE);
BOOL InitInstance(HINSTANCE, int);
extern HWND hWndMain; // Main Window Handle
extern BOOL bWaitMultiple;
extern BOOL bFastFood;
#define P_DELAY bFastFood ? rand()/25 : ((rand()%5)+1)*1000 /*控制進程時間*/
int gDinerState[PHILOSOPHERS];
int gChopstickState[PHILOSOPHERS];
HANDLE gchopStick[PHILOSOPHERS]; /* 1 chopstick between each philopher and his neighbor*/
#undef PostMessage
#define PostMessage SendMessage
/*本函數實現了死鎖與不死鎖兩種狀態
區別僅在調用WaitForMultipleObjects()WaitForSingleObjects()函數
調用WaitForMultipleObjects,哲學家線程需要等待左右筷子,若僅有一邊筷子
則不占有,繼續等待,直到有一雙筷子才占據
調用WaitForSingleObjects,哲學家線程先等待左邊筷子,占有后,再等待右邊筷子
因而容易造成死鎖
*/
DWORD WINAPI PhilosopherThread(LPVOID pVoid)
{
HANDLE myChopsticks[2];
int iPhilosopher = (int) pVoid;
int iLeftChopstick = iPhilosopher;
int iRightChopstick = iLeftChopstick + 1;
DWORD result;
if (iRightChopstick > PHILOSOPHERS-1) //筷子編號過了5就使它為0
iRightChopstick = 0;
//Randomize the random number generator
srand( (unsigned)time( NULL ) * (iPhilosopher + 1) );//????????????????????????????????
// remember handles for my chopsticks
myChopsticks[0] = gchopStick[iLeftChopstick]; //定義哲學家的左右筷子
myChopsticks[1] = gchopStick[iRightChopstick];
gDinerState[iPhilosopher] = RESTING; //wants chopsticks
Sleep(P_DELAY);
for(;;)
{
if (bWaitMultiple == FALSE) //into deadlock state
{
// Wait until both of my chopsticks are available
gDinerState[iPhilosopher] = WAITING; //wants chopsticks
PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
result = WaitForSingleObject(gchopStick[iLeftChopstick], INFINITE); //just wait for leftchopstick
MTVERIFY(result == WAIT_OBJECT_0);
gChopstickState[iLeftChopstick] = iPhilosopher; //標示左筷子已被占有
Sleep(P_DELAY/4);
gDinerState[iPhilosopher] = WAITING; //wants chopsticks
PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
result = WaitForSingleObject(gchopStick[iRightChopstick], INFINITE);
MTVERIFY(result == WAIT_OBJECT_0);
gChopstickState[iRightChopstick] = iPhilosopher; //占據右筷子
}
else //never into deadlock state
{
// Wait until both of my chopsticks are available
gDinerState[iPhilosopher] = WAITING; //wants chopsticks
PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
result = WaitForMultipleObjects(2, myChopsticks, TRUE, INFINITE); //一直等待直到myChopsticks都具備
MTVERIFY(result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + 2);
gChopstickState[iLeftChopstick] = iPhilosopher;
gChopstickState[iRightChopstick] = iPhilosopher;
}
// Philosopher can now eat a grain of rice
gDinerState[iPhilosopher] = EATING; //philosopher is eating
PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
Sleep(P_DELAY);
// Put down chopsticks
gDinerState[iPhilosopher] = RESTING; //philosopher is resting
gChopstickState[iRightChopstick] = UNUSED;
gChopstickState[iLeftChopstick] = UNUSED;
PostMessage(hWndMain, WM_FORCE_REPAINT,0 ,0);
MTVERIFY( ReleaseMutex(gchopStick[iLeftChopstick]) ); //釋放筷子資源
MTVERIFY( ReleaseMutex(gchopStick[iRightChopstick]) );
// Philosopher can now meditate
Sleep(P_DELAY);
} // end for
return 0;
}
int Diner(void)
{
HANDLE hThread[PHILOSOPHERS];
DWORD dwThreadId;
int i;
for (i=0; i < PHILOSOPHERS; i++)
{
//Initialize the chopsitcks to unused
gChopstickState[i] = UNUSED;
// initialize the diner state table
gDinerState[i] = 0;
// The Philosophers prepare to eat
//HANDLE CreateMutex(
//LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD
//BOOL bInitialOwner, // initial owner
//LPCTSTR lpName // object name
//);
gchopStick[i] = CreateMutex(NULL, FALSE, NULL); //create non-named mutex in gchopStick
MTVERIFY(gchopStick[i] != NULL); //if creatrmutex fails,print error
}
for (i = 0; i < PHILOSOPHERS; i++)
//parameter0--0:the handle cannot be inherited.
//parameter1--null:the new thread uses the default size for the executable
//parameter4--0: the thread runs immediately after creation
//parameter5 :the variable that receives the thread identifier.
MTVERIFY( hThread[i] = CreateThread(NULL, 0, PhilosopherThread, (LPVOID) i, 0, &dwThreadId ));//啟動進程
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -