Deadlocks and dining Philosophers

The dining philosophers problem, attributed to Dijkstra, describes a situation in which five philosophers sit around a table. There are five plates, five forks (between the plates) and a bowl of spaghetti in the middle of the table. (Some versions use rice and chopsticks but Dijkstra apparently preferred pasta.) Each philosopher needs two forks to eat. How can all of the philosophers eat from time to time without reaching deadlock and starving?

There are many solutions to this problem; part of the difficulty is that there is no one solution. The problem has become a standard way of describing the difficulties that arise when multiple processes compete for a finite number of resources.
One simple solution is to make sure there are only four philosophers at the table; this ensures that at least one will find two forks. Another is to arrange that one of them pick up the left rather than the right fork first. More complicated solutions involve the use of semaphores or messages.



For deadlock to occur, four conditions must be true.

  1. Mutual Exclusion There must be mutual exclusion among the processes. That is, at least one resource must not be shareable.
  2. Hold and Wait At least one process must be holding a resource and waiting to acquire a resource currently held by another process.
  3. No Preemption Resources cannot be taken away from a process; it must release them as a normal event.
  4. Circular Wait A process holding one resource (A) and waiting for another (B) must be matched by another process that needs A and holds B (there can be more than one such process; perhaps one process needs A and holds C, another needs C and holds B.)


When these four conditions hold, deadlock is possible. If each philosopher takes one fork, deadlock ensues; no one can eat until at least one philosopher puts down at least one fork.

There are three general approaches to solving the problem of deadlock:

  1. Prevention One of the four necessary conditions for deadlock may be prevented from occurring. A printer, for example, is not a shareable resource; whatever process is using it must have exclusive use. Other resources may be shareable (read-only files, for instance) and for these the prevention of mutual exclusion would be possible. If all the resources required by a process are known in advance, they can be allocated as a group; then hold-and-wait is not possible. For cpu time, preemption is possible; the state of the preceding process is put on the stack so it is recoverable. Finally, circular wait may be avoided by ranking resources and allowing processes to acquire only resources with a higher rank.
  2. Avoidance To avoid deadlock, it is necessary to know what resources processes will need; then, when a new request is made, it is possible to see if granting it will result in a situation in which deadlock can occur.

    Dijkstra's banking algorithm is one way to achieve this result.

  3. Detection and Recovery If neither of the previous strategies is used, it is necessary to detect deadlock when it occurs and impose some solution; generally to kill some or all of the processes, or to preempt one or more of them. This is rather a brute force approach; if processes need mutual exclusion, for instance, it is for a reason, and simply terminating a process in the middle of writing to a file will result in loss of data.


Which of these methods should we use? All of them. Clearly there are times at which any may be the preferred solution. A systematic way to decide, suggested by Peterson and Silberschatz, is as follows. Divide resources into the following groups, in order of priority:

  1. Internal Resources Resources used by the operating system, for example Process Control Blocks.
  2. Main Memory RAM
  3. Job Resources I/O Devices and files; assignable resources.
  4. Swap Space Hard drive space used by each process to save its state.


Then the following approaches make sense.

  1. Resource ordering - a preventive technique - can be used to allocate internal resources, because these resources are not used by processes.
  2. Since the contents of RAM can be written to disk to allow memory swapping, preemption is possible here; the preempted process can always regain the information from the hard drive.
  3. The resources such as I/O devices needed by a process can usually be known in advance; thus avoidance is a good strategy to avoid deadlock.
  4. Prevention can be achieved by allocating all the space needed at once. This is usually true for storage space requirements.