Dining Philosophers Problem
The Dining Philosophers Problem is a classic problem in computer science and synchronization theory, often used to illustrate synchronization issues and techniques for resolving them. It was formulated by Edsger Dijkstra in 1965.
Here's the scenario with five philosophers (P0 to P4):
Five philosophers sit around a circular table.
Each philosopher thinks and occasionally needs to eat.
Between each pair of philosophers, there is a single chopstick (a total of five chopsticks).
In order to eat, a philosopher must use two chopsticks - the one to their left and the one to their right.
A philosopher can only pick up one chopstick at a time and cannot pick up a chopstick already in use by another philosopher.
After eating, the philosopher puts down both chopsticks and starts thinking again.
The problem illustrates the challenges of resource allocation and avoiding deadlock, where no progress is possible (e.g., if each philosopher picks up the chopstick on their left, then no one can pick up their second chopstick).
Here's a simple pseudo-code to solve this problem:
semaphore chopsticks[5] # One semaphore per chopstick, initially available
def philosopher(id):
while True:
think() # Philosopher is thinking
wait(chopsticks[id]) # Pick up left chopstick
wait(chopsticks[(id + 1) % 5]) # Pick up right chopstick
eat() # Philosopher is eating
signal(chopsticks[id]) # Put down left chopstick
signal(chopsticks[(id + 1) % 5]) # Put down right chopstick
for i in range(5):
start_thread(philosopher, i)
wait(semaphore)
is a function that decrements the semaphore. If the semaphore value is zero, the philosopher must wait.signal(semaphore)
increments the semaphore, potentially waking up other waiting philosophers.Each philosopher is represented as a thread running the
philosopher
function.chopsticks
is an array of semaphores, one for each chopstick.
Deadlock Scenario
Deadlock can occur if each philosopher grabs the chopstick on their left simultaneously. In this case, each philosopher is waiting for the chopstick to their right, which is held by another philosopher. Since no philosopher can grab both chopsticks, no one can eat, and the system is in a deadlock.
To demonstrate this:
Each philosopher executes
wait(chopsticks[id])
and successfully acquires their left chopstick.Now, every philosopher tries to execute
wait(chopsticks[(id + 1) % 5])
to acquire their right chopstick.Since all right chopsticks are already held by the next philosopher, all philosophers are now waiting.
No philosopher can proceed to
eat()
orsignal()
, leading to a deadlock.
Avoiding Deadlock
One common solution to avoid deadlock is to ensure that not all philosophers can pick up chopsticks simultaneously. For example, you can enforce that at most four philosophers can try to acquire chopsticks at any time. This can be done by introducing an additional semaphore to control the number of philosophers allowed to pick up chopsticks. Alternatively, you can modify the protocol for acquiring chopsticks, such as having one philosopher pick up the right chopstick first, while others pick up the left first.
Subscribe to my newsletter
Read articles from Jyotiprakash Mishra directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
Jyotiprakash Mishra
Jyotiprakash Mishra
I am Jyotiprakash, a deeply driven computer systems engineer, software developer, teacher, and philosopher. With a decade of professional experience, I have contributed to various cutting-edge software products in network security, mobile apps, and healthcare software at renowned companies like Oracle, Yahoo, and Epic. My academic journey has taken me to prestigious institutions such as the University of Wisconsin-Madison and BITS Pilani in India, where I consistently ranked among the top of my class. At my core, I am a computer enthusiast with a profound interest in understanding the intricacies of computer programming. My skills are not limited to application programming in Java; I have also delved deeply into computer hardware, learning about various architectures, low-level assembly programming, Linux kernel implementation, and writing device drivers. The contributions of Linus Torvalds, Ken Thompson, and Dennis Ritchie—who revolutionized the computer industry—inspire me. I believe that real contributions to computer science are made by mastering all levels of abstraction and understanding systems inside out. In addition to my professional pursuits, I am passionate about teaching and sharing knowledge. I have spent two years as a teaching assistant at UW Madison, where I taught complex concepts in operating systems, computer graphics, and data structures to both graduate and undergraduate students. Currently, I am an assistant professor at KIIT, Bhubaneswar, where I continue to teach computer science to undergraduate and graduate students. I am also working on writing a few free books on systems programming, as I believe in freely sharing knowledge to empower others.