using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace TestSemaphore
{
class CriticalSection : IDisposable
{
Mutex _mutex;
public CriticalSection(Mutex mutex)
{
_mutex = mutex;
}
public void Enter()
{
_mutex.WaitOne();
}
#region IDisposable Members
public void Dispose()
{
_mutex.ReleaseMutex();
}
#endregion
}
class PhilosopherSample
{
enum State
{
Thinking,
Hungry,
Eating,
}
DateTime _endTime = DateTime.Now.AddSeconds(5);
Random _ran = new Random();
State[] _philosopher = new State[5];
Semaphore[] _fork = new Semaphore[5];
Mutex _mutex = new Mutex();
CriticalSection _criticalSection;
public void Run()
{
_criticalSection = new CriticalSection(_mutex);
Do5Times(delegate(int i) { _fork[i] = new Semaphore(0, 1); });
Do5Times(delegate(int i) { new Thread(Philosopher).Start(i); });
}
delegate void Action(int i);
void Do5Times(Action ac)
{
for (int i = 0; i < 5; i++)
{
ac(i);
}
}
void Philosopher(object i)
{
int id = (int)i;
while (DateTime.Now < _endTime)
{
// take forks
using (CriticalSection)
{
_philosopher[id] = State.Hungry;
Test(id);
}
_fork[id].WaitOne();
// eat
Console.WriteLine("Philosopher " + id + " is eating...");
Thread.Sleep(_ran.Next(2000));
++_count[id];
// put forks
using (CriticalSection)
{
_philosopher[id] = State.Thinking;
Console.WriteLine("Philosopher " + id + " puts forks");
Test((id + 4) % 5);
Test((id + 1) % 5);
}
}
}
CriticalSection CriticalSection
{
get
{
_criticalSection.Enter();
return _criticalSection;
}
}
void Test(int id)
{
if (_philosopher[id] == State.Hungry && _philosopher[(id + 4) % 5] != State.Eating && _philosopher[(id + 1) % 5] != State.Eating)
{
_philosopher[id] = State.Eating;
_fork[id].Release();
}
}
static void Main(string[] args)
{
new PhilosopherSample().Run();
Console.ReadLine();
}
}
}