Philosophers
An elegant solution to the classic Dining Philosophers problem using threads and mutexes in C to avoid deadlocks and data races.
2021-12-01

Philosophers
The classic Dining Philosophers problem, implemented in C with POSIX threads and mutexes. N philosophers sit around a table with one fork between each adjacent pair. To eat, a philosopher needs both forks. If they go too long without eating, they die.
The challenge is making sure that doesn't happen.
The rules
- Each philosopher runs as its own thread
- Each fork is a mutex shared between two philosophers
- Philosophers can't communicate or see each other's state
- A philosopher dies if they haven't eaten within
time_to_diems - No deadlocks allowed
Usage
./philo number_of_philosophers time_to_die time_to_eat time_to_sleep [must_eat]
./philo 5 800 200 200 # no one should die
./philo 5 800 200 200 7 # stop after each eats 7 times
./philo 1 800 200 200 # one philosopher always dies| Argument | Description |
|---|---|
| number_of_philosophers | How many philosophers (and forks) |
| time_to_die (ms) | Max time without eating before death |
| time_to_eat (ms) | How long eating takes |
| time_to_sleep (ms) | How long sleeping takes |
| must_eat (optional) | Stop once everyone eats this many times |
Implementation details
Threading: Each philosopher is a pthread. Global state lives in a shared t_data struct, per-philosopher state (last meal time, eat count) in each t_philo.
Deadlock prevention: Philosophers are given asymmetric fork pickup orders based on their ID, which breaks the circular wait condition.
Death detection: A monitor thread continuously checks if any philosopher has exceeded time_to_die since their last meal. On detection, it sets a shared flag and all threads exit cleanly.
Output
timestamp_in_ms N has taken a fork
timestamp_in_ms N is eating
timestamp_in_ms N is sleeping
timestamp_in_ms N is thinking
timestamp_in_ms N died
Death is logged within 10ms of actually happening.
SCREENSHOTS // 01 FRAMES
