Skip to content

itselcid/philo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🍝 Philosophers

A multithreaded solution to the classic Dining Philosophers Problem, implemented in C using POSIX threads (pthreads) and mutexes.

This project is part of the 42 School curriculum and demonstrates concurrent programming concepts including thread synchronization, mutex locks, and deadlock prevention.

📋 Table of Contents

📖 About

The Dining Philosophers problem is a classic synchronization problem that illustrates the challenges of allocating shared resources among multiple processes without causing deadlock or starvation.

In this simulation:

  • N philosophers sit around a circular table
  • Each philosopher alternates between thinking, eating, and sleeping
  • There are N forks on the table (one between each pair of philosophers)
  • A philosopher needs two forks to eat
  • If a philosopher doesn't eat within a specified time, they die

🧩 The Problem

The challenge is to design a solution where:

  • No philosopher starves (everyone gets to eat)
  • No deadlock occurs (philosophers don't get stuck waiting forever)
  • The simulation runs correctly with proper synchronization

⚙️ How It Works

  1. Initialization: Philosophers and forks (mutexes) are created based on input arguments
  2. Thread Creation: Each philosopher runs in their own thread
  3. Health Monitoring: A dedicated thread monitors if any philosopher has starved
  4. Fork Acquisition: Philosophers use an odd/even strategy to prevent deadlock:
    • Even-numbered philosophers pick up the left fork first
    • Odd-numbered philosophers pick up the right fork first
  5. Lifecycle Loop: Each philosopher repeats: take forks → eat → release forks → sleep → think
  6. Termination: Simulation ends when a philosopher dies or all have eaten the required number of meals

📁 Project Structure

File Description
philosopher.h Header file with struct definitions, macros, and function prototypes
philosopher.c Main entry point, initialization of philosophers and simulation setup
philosopher_utils.c Utility functions: ft_atoi, argument validation, time functions, ft_usleep
actions.c Philosopher actions: eating, sleeping, thinking, status printing
simulation.c Simulation control, health monitoring thread, thread management
Makefile Build automation with standard rules

🛠️ Requirements

  • OS: Linux, macOS, or any POSIX-compatible system
  • Compiler: cc (GCC/Clang) with C99 support
  • Libraries: POSIX Threads (pthread)
  • Tools: make

🚀 Installation

Clone the repository and compile:

git clone https://github.com/itselcid/philo.git
cd philo
make

Makefile Commands

Command Description
make Compile the project
make clean Remove object files
make fclean Remove object files and executable
make re Rebuild the project from scratch

📝 Usage

./philo number_of_philosophers time_to_die time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat]

Arguments

Argument Description
number_of_philosophers Number of philosophers (and forks) at the table
time_to_die Time in milliseconds a philosopher can survive without eating
time_to_eat Time in milliseconds it takes for a philosopher to eat
time_to_sleep Time in milliseconds a philosopher spends sleeping
number_of_times_each_philosopher_must_eat (Optional) Simulation stops when all philosophers have eaten at least this many times

Examples

Basic simulation with 5 philosophers:

./philo 5 800 200 200

Stop after each philosopher eats 7 times:

./philo 5 800 200 200 7

Edge case - single philosopher (will die):

./philo 1 800 200 200

📺 Example Output

0 1 has taken a fork
0 1 has taken a fork
0 1 is eating
0 2 has taken a fork
0 2 has taken a fork
0 2 is eating
200 1 is sleeping
200 2 is sleeping
400 1 is thinking
400 2 is thinking
... 

Each line shows: timestamp_in_ms philosopher_id action

Possible Actions

  • has taken a fork
  • is eating
  • is sleeping
  • is thinking
  • died

🔧 Implementation Details

Synchronization Strategy

Mechanism Purpose
Mutex per fork Ensures only one philosopher can hold a fork at a time
Print mutex Prevents interleaved/garbled output from multiple threads
Simulation mutex Thread-safe access to the simulation running state

Deadlock Prevention

The project uses an odd/even fork acquisition order:

  • Even philosophers: Pick up left_fork first, then right_fork
  • Odd philosophers: Pick up right_fork first, then left_fork
  • Odd philosophers also start with a small delay (1ms) to reduce contention

This asymmetric approach breaks the circular wait condition that would otherwise cause deadlock.

Health Monitoring

A dedicated health_center thread continuously checks if any philosopher has exceeded their time_to_die since their last meal. If so, it prints the death message and stops the simulation.

Precision Timing

  • Uses gettimeofday() for millisecond-precision timestamps
  • Custom ft_usleep() with busy-waiting for more accurate sleep durations
  • Respects simulation state to exit sleep early when simulation ends

👤 Author

oessaadi - 42 Student


This project was created as part of the 42 School curriculum.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published