Skip to content

JMADIL/PHILO

Repository files navigation

🍝 Philosophers

I never thought philosophy would be so deadly — 42 Network project

42 School Language License


📖 About

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.

🍽️ The Problem

         🍝
    🍴        🍴
  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!

✨ Features

  • 🧵 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

🚀 Getting Started

Prerequisites

  • GCC compiler
  • Make
  • pthread library (standard on Linux / macOS)
  • A UNIX-based OS

Build

git clone https://github.com/JMADIL/PHILO.git
cd PHILO
make

Usage

./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

Examples

# 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 200

Output

0       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

📂 Project Structure

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)

🏗️ Architecture

┌─────────────────────────────────────────────┐
│                 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 ☠️   │
└─────────────────────────────────────────────┘

🔑 Key Concepts Learned

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

🔧 Allowed Functions

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

👤 Author

Adil Jamoun@JMADIL

🏫 1337 Coding School (42 Network) — Morocco

About

A simulation of the classic dining philosophers problem to manage multithreading and resource sharing. It runs multiple concurrent threads that must alternate between eating, thinking, and sleeping while sharing a limited set of resources without locking up.

Topics

Resources

Stars

Watchers

Forks

Contributors