Overview
The monitor thread runs independently of philosopher threads and continuously checks for two termination conditions:- Death detection: Has any philosopher exceeded
time_to_diewithout eating? - Meal completion: Have all philosophers completed their required meals?
dead flag, causing all philosophers to exit their routines.
The monitor Function
Monitoring Loop
- The monitor runs in an infinite loop
- On each iteration, it checks both death and meal completion
- The loop breaks when either check returns 1
- No sleep delay between checks (continuous monitoring)
The monitor is created as the first thread before any philosopher threads, ensuring death detection is active from the simulation start.
Death Detection
check_if_dead Function
Handle Death
If death detected:
- Print the death message
- Lock the dead flag mutex
- Set
*philos->dead = 1 - Unlock the mutex
- Return 1 to end monitoring
philosopher_dead Function
Death Criteria
A philosopher is considered dead when both conditions are true:- Time Exceeded
- Not Currently Eating
time_to_die.The
lock_meal mutex protects access to both last_meal_time and eating, ensuring the monitor reads consistent state even while philosophers are updating these values.Why Check eating Flag?
Race Condition Prevention
Race Condition Prevention
Without checking
eating, there’s a brief window where:- Philosopher acquires both forks
- Monitor checks time (exceeds
time_to_die) - Monitor declares philosopher dead
- Philosopher updates
last_meal_time(too late)
eating flag acts as a “grace period” indicator.Implementation Detail
Implementation Detail
In This ensures the monitor won’t incorrectly detect death while the philosopher is eating.
ft_eat(), the sequence is:Meal Completion Tracking
check_if_all_ate Function
Execution Flow
Check if Meal Limit Exists
Count Finished Philosophers
Iterate through all philosophers, locking
lock_meal to safely read meal_counter. Increment finished_eating for each philosopher who has met or exceeded their meal requirement.This check uses
>= instead of == for the meal counter comparison, providing flexibility if a philosopher somehow exceeds the exact count due to timing.Thread Safety
Mutex Usage
- lock_meal
- lock_dead
- lock_write
Protects philosopher meal state:
meal_counterlast_meal_timeeatingflag
The print_message Function
Purpose
- Serializes all console output to prevent interleaved messages
- Formats output as:
<timestamp> <philosopher_id> <message> - Checks
dead_loopbefore printing to avoid messages after simulation ends
The
dead_loop check inside print_message ensures that once the dead flag is set, no further status messages are printed, even if a philosopher thread hasn’t exited yet.Monitoring Strategy
Continuous vs. Periodic Checking
This implementation uses continuous monitoring:- Immediate death detection (minimal delay)
- No risk of missing death between sleep intervals
- Critical for tight
time_to_dieconstraints
- Higher CPU usage from constant checking
- Acceptable for this simulation’s requirements
Alternative: Periodic Monitoring
Alternative: Periodic Monitoring
Some implementations add a small sleep:This reduces CPU usage but adds detection latency.