using Microsoft.VisualStudio.TestTools.UnitTesting;
public class DiningPhilosophers
private static Mutex[] forks;
private static Thread[] philosophers;
private static int numPhilosophers;
private static Random random = new Random();
public void DiningPhilosopher(int n)
forks = new Mutex[numPhilosophers];
philosophers = new Thread[numPhilosophers];
for (int i = 0; i < numPhilosophers; i++)
for (int i = 0; i < numPhilosophers; i++)
philosophers[i] = new Thread(() => Philosopher(philosopherId));
philosophers[i].Name = "Philosopher " + i;
foreach (Thread philosopher in philosophers)
Console.WriteLine("Simulation ended.");
static void Philosopher(int id)
int rightFork = (id + 1) % numPhilosophers;
Console.WriteLine($"{Thread.CurrentThread.Name} is thinking.");
Thread.Sleep(random.Next(100, 500));
Console.WriteLine($"{Thread.CurrentThread.Name} is hungry.");
if (forks[leftFork].WaitOne(100))
Console.WriteLine($"{Thread.CurrentThread.Name} picked up left fork.");
if (forks[rightFork].WaitOne(100))
Console.WriteLine($"{Thread.CurrentThread.Name} picked up right fork and is eating.");
Thread.Sleep(random.Next(100, 500));
forks[rightFork].ReleaseMutex();
Console.WriteLine($"{Thread.CurrentThread.Name} put down right fork.");
Console.WriteLine($"{Thread.CurrentThread.Name} could not get right fork, returning left fork.");
forks[leftFork].ReleaseMutex();
Console.WriteLine($"{Thread.CurrentThread.Name} put down left fork.");
Thread.Sleep(random.Next(50, 200));
forks[leftFork].ReleaseMutex();
Console.WriteLine($"{Thread.CurrentThread.Name} put down left fork.");
Console.WriteLine($"{Thread.CurrentThread.Name} could not get left fork, waiting.");
Thread.Sleep(random.Next(50, 200));
catch (ThreadAbortException)
Console.WriteLine($"{Thread.CurrentThread.Name} simulation aborted.");
if (forks[leftFork].WaitOne(0))
forks[leftFork].ReleaseMutex();
if (forks[rightFork].WaitOne(0))
forks[rightFork].ReleaseMutex();
public class DiningPhilosophersTests
public void DiningPhilosopher_ValidInput_RunsWithoutDeadlock()
DiningPhilosophers dp = new DiningPhilosophers();
StringWriter consoleOutput = new StringWriter();
Console.SetOut(consoleOutput);
dp.DiningPhilosopher(numPhilosophers);
Assert.Fail("Exception thrown during execution: " + ex.Message);
string output = consoleOutput.ToString();
Assert.IsFalse(string.IsNullOrEmpty(output), "No output was produced. Possible deadlock?");
Console.SetOut(Console.Out);
[ExpectedException(typeof(ThreadAbortException))]
public void DiningPhilosopher_ZeroPhilosophers_NoException()
DiningPhilosophers dp = new DiningPhilosophers();
dp.DiningPhilosopher(numPhilosophers);