Overview
Each philosopher thread executes thephilo_routine function, which implements the classic eat-sleep-think cycle. The routine continues until the simulation ends (either by a death or all philosophers finishing their meals).
The philo_routine Function
Execution Flow
1. Thread Initialization
2. Even Philosopher Delay
Even-numbered philosophers are delayed by 1 millisecond before entering the main loop. This staggered start helps prevent all philosophers from attempting to grab forks simultaneously, reducing initial deadlock risk.
- Odd philosophers (1, 3, 5…) start immediately
- Even philosophers (2, 4, 6…) wait 1ms
- This creates an alternating pattern where philosophers are slightly out of phase
- Reduces contention for forks at simulation start
3. Main Execution Loop
dead_loop returns true (simulation ended).
Death Detection: dead_loop
Thedead_loop function is called at every loop iteration to check if the simulation has ended:
How It Works
- Simulation Active
- Simulation Ended
The comma operator in the return statement ensures the mutex is unlocked before returning:
(unlock, 1) executes unlock first, then returns 1.Thread Safety
- The
lock_deadmutex protects concurrent access to the shareddeadflag - All philosophers check the same flag pointer:
*philo->dead - The monitor thread sets this flag when:
- A philosopher dies (exceeds
time_to_diewithout eating) - All philosophers complete their required meals
- A philosopher dies (exceeds
Timing and Flow Control
Action Sequence
No Delay in Thinking
Notice thatft_think does not include a sleep call:
Preventing Race Conditions
Death Flag Access
Death Flag Access
The
dead_loop function always locks lock_dead before reading the flag, preventing race conditions between:- Philosopher threads checking the flag
- Monitor thread setting the flag
Loop Consistency
Loop Consistency
Checking
dead_loop at the start of each iteration ensures:- Clean exits when simulation ends
- No philosophers continue acting after death is detected
- Graceful thread termination
Thread Creation
Philosopher threads are created inft_pthread_create:
- A unique thread handle stored in
philos[i].thread - A pointer to their own
t_philostructure as the thread argument - The
philo_routinefunction as their entry point
The monitor thread is created before philosopher threads, ensuring it’s ready to detect deaths from the very beginning of the simulation.