/*
* Dining.c
*
* Sample code for "Multithreading Applications in Win32"
* This sample is discussed in Chapter 4.
*
* Graphically demonstrates the problem of the
* dining philosophers.
*/
ret = MessageBox(hWndMain, "Do you want to use WaitForMultipleObjects()?\n\n"
"If you select Yes, then the application will run all day.\n"
"If you select No, then the application can deadlock.\n",
"Wait Mode", MB_YESNO);
if (ret == IDYES)
bWaitMultiple = TRUE;
else
{
bWaitMultiple = FALSE;
ret = MessageBox(hWndMain, "Do you want fast philosophers?\n\n"
"If you select Yes, then it will deadlock much faster.\n",
"Wait Mode", MB_YESNO);
if (ret == IDYES)
bFastFood = TRUE;
else
bFastFood = FALSE;
}
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
int i;
if (!hPrevInstance)
if (!InitApplication(hInstance))
return (FALSE);
if (!InitInstance(hInstance, nCmdShow))
return (FALSE);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// Clear the table
for (i = 0; i < PHILOSOPHERS; i++)
CloseHandle(gchopStick[i]);
/*
* 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.
*/
for(;;)
{
if (bWaitMultiple == FALSE)
{
// 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);
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
{
// 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);
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
gchopStick[i] = CreateMutex(NULL, FALSE, NULL);
MTVERIFY(gchopStick[i] != NULL);
}
for (i = 0; i < PHILOSOPHERS; i++)
MTVERIFY( hThread[i] = CreateThread(NULL, 0, PhilosopherThread, (LPVOID) i, 0, &dwThreadId ));