I never thought philosophy would be so deadly — 42 Network project
Philosophers is a 42 school project that solves the classic Dining Philosophers Problem — a fundamental concurrency challenge in computer science. Multiple philosopher threads sit around a table, and must eat, think, and sleep in a cycle without starving to death, while sharing forks (mutexes) with their neighbors.
This project is a deep dive into multithreading, mutexes, race conditions, and deadlock prevention.
🍝
🍴 🍴
P1 P2
🍴 ╭──────╮ 🍴
│ TABLE │
🍴 ╰──────╯ 🍴
P5 P3
🍴 🍴
P4
🍴
Rules:
• Each philosopher needs TWO forks to eat
• Forks are shared between neighbors
• If a philosopher doesn't eat in time → they die ☠️
• Goal: Keep everyone alive!
- 🧵 Multithreading — Each philosopher runs in their own thread
- 🔒 Mutex-based Forks — Forks are protected by mutexes to prevent data races
- ⏱️ Precise Timing — Microsecond-accurate timestamps for all actions
- 💀 Death Monitoring — A dedicated monitor detects starvation instantly
- 🛡️ Deadlock Prevention — Smart fork-picking order prevents deadlocks
- 🧹 Clean Exit — Proper resource cleanup on simulation end
- GCC compiler
- Make
- pthread library (standard on Linux / macOS)
- A UNIX-based OS
git clone https://github.com/JMADIL/PHILO.git
cd PHILO
make./philo <number_of_philosophers> <time_to_die> <time_to_eat> <time_to_sleep> [meals_required]| Argument | Description |
|---|---|
number_of_philosophers |
Number of philosophers (and forks) |
time_to_die (ms) |
Time before a philosopher starves |
time_to_eat (ms) |
Duration of eating |
time_to_sleep (ms) |
Duration of sleeping |
meals_required |
(optional) Simulation ends when all have eaten this many times |
# 5 philosophers, 800ms die, 200ms eat, 200ms sleep → should survive
./philo 5 800 200 200
# 4 philosophers, each must eat 7 times → simulation ends after all are fed
./philo 4 410 200 200 7
# 1 philosopher, only 1 fork → will die (can't eat with 1 fork)
./philo 1 800 200 2000 1 has taken a fork
0 1 has taken a fork
0 1 is eating
200 1 is sleeping
200 2 has taken a fork
...
Format: timestamp_in_ms philosopher_id action
PHILO/
├── Makefile # Build system
├── philo.h # Header with structs & prototypes
├── main.c # Entry point, argument parsing, initialization
├── validate_args.c # Input validation
├── begin_simulation.c # Thread creation & simulation start
├── cycle.c # Philosopher lifecycle (eat → sleep → think)
├── end_simulation.c # Death monitoring & simulation termination
├── cleanup.c # Resource cleanup (mutexes, memory)
├── philo_utils.c # Philosopher-specific utility functions
└── utils.c # General utilities (ft_atoi, time helpers)
┌─────────────────────────────────────────────┐
│ MAIN THREAD │
│ Parse args → Init data → Create threads │
├─────────────────────────────────────────────┤
│ │
│ Thread 1 Thread 2 Thread 3 ... │
│ ┌───────┐ ┌───────┐ ┌───────┐ │
│ │Philo 1│ │Philo 2│ │Philo 3│ │
│ │ eat │ │ think │ │ sleep │ │
│ │ sleep │ │ eat │ │ think │ │
│ │ think │ │ sleep │ │ eat │ │
│ └───────┘ └───────┘ └───────┘ │
│ ↕ ↕ ↕ │
│ 🔒Fork1 🔒Fork2 🔒Fork3 (mutexes) │
│ │
├─────────────────────────────────────────────┤
│ MONITOR THREAD │
│ Continuously checks if any philo died ☠️ │
└─────────────────────────────────────────────┘
| Concept | Description |
|---|---|
| Threads | Creating and managing threads with pthread_create / pthread_join |
| Mutexes | Protecting shared resources with pthread_mutex_lock / unlock |
| Race Conditions | Understanding and preventing concurrent data access bugs |
| Deadlocks | Avoiding circular wait conditions with ordered lock acquisition |
| Timing | Precise time tracking with gettimeofday() and usleep() |
| Resource Management | Proper initialization and cleanup of threads and mutexes |
memset · printf · malloc · free · write · usleep · gettimeofday · pthread_create · pthread_detach · pthread_join · pthread_mutex_init · pthread_mutex_destroy · pthread_mutex_lock · pthread_mutex_unlock
Adil Jamoun — @JMADIL
🏫 1337 Coding School (42 Network) — Morocco