Created
August 23, 2011 08:41
-
-
Save johnnykv/1164673 to your computer and use it in GitHub Desktop.
C# solution for dining philosophers.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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