Skip to content

Instantly share code, notes, and snippets.

@johnnykv
Created August 23, 2011 08:41
Show Gist options
  • Save johnnykv/1164673 to your computer and use it in GitHub Desktop.
Save johnnykv/1164673 to your computer and use it in GitHub Desktop.
C# solution for dining philosophers.
//C# solution for dining philosophers.
//Johnny Vestergaard - 2011
//jkv@unixcluster.dk
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace DiningPhil
{
class Program
{
static void Main(string[] args)
{
//hver element indikere om et gaffel er i brug (true) eller ledig (false)
bool[] forks = new bool[5];
Filosof[] filosoffer = new Filosof[5];
//Start 5 tråde med hver sin filosof.
for (int x = 0; x < filosoffer.Length; x++)
{
Filosof filosof = new Filosof(forks, x);
filosoffer[x] = filosof;
Thread filosofTraad = new Thread(filosof.Start);
filosofTraad.Name = x.ToString();
filosofTraad.Start();
}
//Holder til status koder på de 5 filosoffer.
//V = Venter på lock, T = tænker, S = Spiser.
char[] filosofStatus = new char[filosoffer.Length];
while (true)
{
for (int x = 0; x < filosoffer.Length; x++)
{
filosofStatus[x] = filosoffer[x].Status();
}
//Udskriv status koder for filosof 0 .. 5
Console.WriteLine("{0} {1} {2} {3} {4}", filosofStatus[0], filosofStatus[1],
filosofStatus[2], filosofStatus[3], filosofStatus[4]);
//Hvis der trykkes på en tast udskrives akkumuleret antal
//måltilder til de enkelte filosofferne.
if (Console.KeyAvailable)
{
Console.ReadKey();
Console.WriteLine("Antal måltider:");
for (int x = 0; x < filosoffer.Length; x++)
{
Console.WriteLine("Filosof {0}: {1}", filosoffer[x].Number(), filosoffer[x].AntalGangeSpist());
}
}
Thread.Sleep(1000);
}
}
}
class Filosof
{
private bool[] forks;
int number;
int leftfork;
int rightfork;
private int antalGangeSpist;
//alle starter med at tænke.
char status = 'T';
public Filosof(bool[] forks, int number)
{
this.forks = forks;
this.number = number;
//find nummer på venstre og højre gaffel.
leftfork = this.number;
//modulus 5 for at lave round robin for den sidste filosof. ( (4+1) % 5 = 0)
rightfork = (this.number + 1) % 5;
Console.WriteLine("Filosof {0}, left fork: {1}, right fork: {2}", number, leftfork.ToString(), rightfork.ToString());
}
public void Start()
{
Random rand = new Random();
while (true)
{
//tænke sleep
Thread.Sleep(rand.Next(1000, 5000));
status = 'V'; // venter på lock
//Tag gaflerne!
lock (forks)
{
while (forks[rightfork] == true || forks[leftfork] == true)
{
Monitor.Wait(forks);
}
forks[rightfork] = true;
forks[leftfork] = true;
status = 'S'; // spiser
antalGangeSpist++;
Monitor.PulseAll(forks);
}
//spise sleep
Thread.Sleep(rand.Next(1000, 5000));
//færdig med at spise - gaflerne lægges!
lock (forks)
{
//dette burde aldrig ske, inkluderet for at fange
//evt. programmeringsfejl mens der udvikles.
if (forks[rightfork] == false || forks[leftfork] == false)
{
throw new InvalidOperationException("What the fuck!");
}
forks[rightfork] = false;
forks[leftfork] = false;
Monitor.PulseAll(forks);
}
//og vi overgår til tænkning igen...
status = 'T'; // tænker
}
}
internal char Status()
{
return status;
}
internal int AntalGangeSpist()
{
return antalGangeSpist;
}
internal int Number()
{
return number;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment