Home   Cover Cover Cover Cover
 

Dining philosophers

/csbook/solutions/14/A04.cs
using System;
using System.Threading;

// Fork pool used by the philosophers
class Forks {
  bool[] fork = new bool[5]; // initially false, i.e. not used
  
  // Try to pick up the forks with the designated numbers
  public void Get(int left, int right) {
    lock (this) {
      while (fork[left] || fork[right]) Monitor.Wait(this);
      fork[left] = true; fork[right] = true;
    }
  }
  
  // Lay down the forks with the designated numbers
  public void Put(int left, int right) {
    lock(this) {
      fork[left] = false; fork[right] = false;
      Monitor.PulseAll(this);
    }
  }
}

// A dining philosopher
class Philo {
  int n;           // this philosopher's number
  int thinkDelay;  // how long does this philosopher think?
  int eatDelay;    // how long does this philosopher eat
  int left, right; // left and right fork number
  Forks forks;     // forks used by all philosophers

  public Philo (int n, int thinkDelay, int eatDelay, Forks forks) {
    this.n = n;
    this.thinkDelay = thinkDelay; this.eatDelay = eatDelay;
    this.forks = forks;
    left = n == 0 ? 4 : n-1;
    right = (n+1) % 5;
    new Thread(new ThreadStart(Run)).Start();
  }
  
  public void Run() {
    for (;;) {
      try {
        Thread.Sleep(thinkDelay); 
        forks.Get(left, right);
        Console.WriteLine("Philosopher " + n + " is eating...");
        Thread.Sleep(eatDelay);
        forks.Put(left, right);
      } catch { 
        return; 
      }
    }
  }

}

public class PhiloTest {

  public static void Main() {
    Forks forks = new Forks();
    new Philo(0, 100, 500, forks);
    new Philo(1, 200, 400, forks);
    new Philo(2, 300, 300, forks);
    new Philo(3, 400, 200, forks);
    new Philo(4, 500, 100, forks);
  }
}

Sample output of this program:

Philosopher 0 is eating...
Philosopher 1 is eating...
Philosopher 2 is eating...
Philosopher 3 is eating...
Philosopher 1 is eating...
Philosopher 0 is eating...
Philosopher 4 is eating...
Philosopher 2 is eating...
Philosopher 3 is eating...
Philosopher 1 is eating...
Philosopher 0 is eating...
Philosopher 4 is eating...
Philosopher 2 is eating...
Philosopher 3 is eating...
Philosopher 1 is eating...
Philosopher 0 is eating...
Philosopher 4 is eating...
Philosopher 1 is eating...
Philosopher 2 is eating...
Philosopher 0 is eating...
Philosopher 4 is eating...
Philosopher 1 is eating...
Philosopher 2 is eating...
Philosopher 3 is eating...
Philosopher 4 is eating...
Philosopher 1 is eating...
Philosopher 0 is eating...
Philosopher 4 is eating...
Philosopher 3 is eating...
Philosopher 2 is eating...
Philosopher 1 is eating...
Philosopher 0 is eating...
Philosopher 4 is eating...
Philosopher 1 is eating...
Philosopher 2 is eating...
Philosopher 3 is eating...
Philosopher 4 is eating...
Philosopher 0 is eating...
Philosopher 1 is eating...
Philosopher 4 is eating...
Philosopher 2 is eating...
Philosopher 3 is eating...
Philosopher 1 is eating...
Philosopher 0 is eating...
Philosopher 4 is eating...
Philosopher 1 is eating...
Philosopher 2 is eating...
Philosopher 0 is eating...
Philosopher 4 is eating...
Philosopher 1 is eating...
Philosopher 2 is eating...
Philosopher 3 is eating...
Philosopher 4 is eating...
Philosopher 0 is eating...
Philosopher 1 is eating...

As we can see, all philosophers get their turn and none of them has to starve.