// Chapter06.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <string>
#include <windows.h>
#include <process.h>
#include <iostream>
using namespace std;
int const MAX_FORK = 5;
int const MAX_PHILOSOPHER = 5;
HANDLE g_forks[ MAX_FORK ];
HANDLE g_room;
void eat( string const & philosopher );
void think( string const & philosopher );
unsigned int WINAPI startDinner( LPVOID param );
int _tmain(int argc, _TCHAR* argv[])
{
string philo[MAX_PHILOSOPHER] = {"Socrates", "Plato", "Fredeu", "Kant", "Kongja"};
DWORD threadIDs[MAX_PHILOSOPHER];
HANDLE threadHandles[ MAX_PHILOSOPHER ];
for( int i = 0; i < MAX_FORK; ++i )
{
g_forks[ i ] = ::CreateSemaphore( NULL, 1, 1, NULL );
}
g_room = ::CreateSemaphore( NULL, 4, 4, NULL );
for(int i =0; i<MAX_PHILOSOPHER; ++i)
{
threadHandles[i] = (HANDLE) ::_beginthreadex( NULL, 0 , startDinner,(LPVOID*)(&philo[i]),0,(unsigned int *)&threadIDs[i]);
}
DWORD result = ::WaitForMultipleObjects(MAX_PHILOSOPHER, &threadHandles[0],TRUE,INFINITE);
if(result == WAIT_OBJECT_0)
{
}
for( int i = 0; i < MAX_FORK; ++i )
{
::ReleaseSemaphore(g_forks[i],1,NULL);
}
::ReleaseSemaphore(g_room,1,NULL);
for(int i = 0; i< MAX_PHILOSOPHER; ++i)
{
CloseHandle(threadHandles[i]);
CloseHandle(g_forks[i]);
}
CloseHandle(g_room);
return 0;
}
void eat( string const & philosopher )
{
::Sleep( 100 );
cout << philosopher+" eat something.\n";
//printf("%s eat something.\n",philosopher);
}
void think( string const & philosopher )
{
::Sleep( 100 );
cout << philosopher+" think something.\n";
//printf("%s think something.\n",philosopher);
}
unsigned int WINAPI startDinner( LPVOID param )
{
string ch = *((string *)param);
for(int i =0 ; i< MAX_FORK ; i++)
{
think(ch);
DWORD result = ::WaitForSingleObject(g_room,INFINITE);
DWORD result2 = ::WaitForSingleObject(g_forks[i],INFINITE);
result2 = ::WaitForSingleObject(g_forks[i+1%5],INFINITE);
eat(ch);
::ReleaseSemaphore(g_forks[i+1%5],1,NULL);
::ReleaseSemaphore(g_forks[i],1,NULL);
::ReleaseSemaphore(g_room,1,NULL);
}
return 0;
}