Non-blocking solution to the dining philosophers
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Introduction
The Dining Philosophers problem is a classic concurrency problem that illustrates the challenges of resource sharing in a multi-threaded environment. The problem was originally formulated by Edsger Dijkstra and involves philosophers seated around a table, each needing two forks to eat their meals yet having only five forks in total. This leads to the potential issue of deadlock, where each philosopher holds one fork and waits indefinitely for another—a situation that represents a deadlock in computational terms.
This article delves into non-blocking solutions for this problem, offering technical explanations and examples. Non-blocking approaches ensure that no philosopher is stuck forever, thereby preventing deadlock while allowing some degree of concurrency.
Non-blocking Approach
The non-blocking solution to the Dining Philosophers problem aims to eliminate deadlock by ensuring that no philosopher waits indefinitely. Here's a more refined look into this:
Asymmetric Allocation Strategy
One straightforward non-blocking strategy is to employ an asymmetric allocation of resources. In this model, philosophers have a pre-defined order for picking up forks, reducing the risk of a cyclic wait (which causes deadlock).
Algorithm Explanation
- Even/Odd Differentiation: Philosophers are numbered from 0 to n-1. Philosophers with odd numbers pick up their left fork first, whereas those with even numbers pick up their right fork first.
- Non-blocking Pickup: Once a philosopher picks up their first fork, they will attempt to pick up the second. If they cannot acquire the second fork, they must release the first and try again after a certain wait period.
- Eating and Release: Once both forks are acquired, the philosopher eats, releases both forks, and then contemplates, allowing others to continue.
Implementation Example
Below is a snippet of a strategy using Python's threading and a naive sleep-based wait for acquiring forks:
- Avoidance of Cyclic Wait: By pre-defining the order of fork acquisition, cyclic waits are eliminated, preventing deadlock.
- Backoff or Retry Mechanism: Philosophers can relinquish resources and retry after a short wait, promoting fairness and preventing starvation.
- Independence and Asynchronous Operations: Each philosopher operates independently, increasing total throughput and utility of the available resources.
Related reading
- Non-intersecting line segments while minimizing the cumulative length
- Non-recursive depth first search algorithm
- Non-recursive implementation of Flood Fill algorithm?
- Non-Recursive Merge Sort
- Non-Generic TaskCompletionSource or alternative
- Non blocking system call and mode switch
- Non-recursive merge sort with two nested loops - how?
- Non-trivial algorithm conversion from imperative to functional

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.