The dining philosophers problem illustrates non-composability of low-level synchronization primitives like semaphores. It is a modification of a problem posed by Edsger Dijkstra.

Five philosophers, Aristotle, Kant, Spinoza, Marx, and Russell (the tasks) spend their time thinking and eating spaghetti. They eat at a round table with five individual seats. For eating each philosopher needs two forks (the resources). There are five forks on the table, one left and one right of each seat. When a philosopher cannot grab both forks it sits and waits. Eating takes random time, then the philosopher puts the forks down and leaves the dining room. After spending some random time thinking about the nature of the universe, he again becomes hungry, and the circle repeats itself.

It can be observed that a straightforward solution, when forks are implemented by semaphores, is exposed to deadlock. There exist two deadlock states when all five philosophers are sitting at the table holding one fork each. One deadlock state is when each philosopher has grabbed the fork left of him, and another is when each has the fork on his right.

There are many solutions of the problem, program at least one, and explain how the deadlock is prevented.

Imports System.Threading
Module Module1
   Public rnd As New Random
 
   Sub Main()
       'Aristotle, Kant, Spinoza, Marx, and Russel 
       Dim f1 As New Fork(1)
       Dim f2 As New Fork(2)
       Dim f3 As New Fork(3)
       Dim f4 As New Fork(4)
       Dim f5 As New Fork(5)
 
       Console.WriteLine("1: Deadlock")
       Console.WriteLine("2: Live lock")
       Console.WriteLine("3: Working")
       Select Console.ReadLine
           Case "1"
               Using _
                   Aristotle As New SelfishPhilosopher("Aristotle", f1, f2), _
                   Kant As New SelfishPhilosopher("Kant", f2, f3), _
                   Spinoza As New SelfishPhilosopher("Spinoza", f3, f4), _
                   Marx As New SelfishPhilosopher("Marx", f4, f5), _
                   Russel As New SelfishPhilosopher("Russel", f5, f1)
 
                   Console.ReadLine()
               End Using
           Case "2"
               Using _
                   Aristotle As New SelflessPhilosopher("Aristotle", f1, f2), _
                   Kant As New SelflessPhilosopher("Kant", f2, f3), _
                   Spinoza As New SelflessPhilosopher("Spinoza", f3, f4), _
                   Marx As New SelflessPhilosopher("Marx", f4, f5), _
                   Russel As New SelflessPhilosopher("Russel", f5, f1)
 
                   Console.ReadLine()
               End Using
           Case "3"
               Using _
                   Aristotle As New WisePhilosopher("Aristotle", f1, f2), _
                   Kant As New WisePhilosopher("Kant", f2, f3), _
                   Spinoza As New WisePhilosopher("Spinoza", f3, f4), _
                   Marx As New WisePhilosopher("Marx", f4, f5), _
                   Russel As New WisePhilosopher("Russel", f5, f1)
 
                   Console.ReadLine()
               End Using
       End Select
   End Sub
 
End Module