Skip to main content

Quickstart

After building the project, run the simulation with the required parameters:
./philo number_of_philosophers time_to_die time_to_eat time_to_sleep [number_of_times_each_philosopher_must_eat]
All time values are in milliseconds. The fifth parameter is optional.

Basic Examples

./philo 4 410 200 200

Understanding the Output

The program outputs timestamped philosopher actions in the following format:
[timestamp_in_ms] [philosopher_id] [action]

Example Output

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

Output Actions

The simulation logs the following actions:
  • has taken a fork - Philosopher picks up a fork (logged twice per philosopher)
  • is eating - Philosopher begins eating
  • is sleeping - Philosopher begins sleeping
  • is thinking - Philosopher begins thinking
  • died - A philosopher has died from starvation
The timestamp represents milliseconds elapsed since the simulation started. All timestamps are relative to the start time.

Simulation Behavior

Normal Execution

When parameters are set correctly:
  1. Philosophers alternate between eating, sleeping, and thinking
  2. Each philosopher needs two forks to eat
  3. Forks are shared between adjacent philosophers
  4. The simulation continues until a philosopher dies or all complete their meals (if the optional parameter is provided)

Completion Scenarios

The simulation ends when:
  1. A philosopher dies: If any philosopher doesn’t eat within time_to_die milliseconds since their last meal
  2. All philosophers finish eating: If the optional meal count parameter is provided and all philosophers eat that many times

Edge Cases

./philo 1 800 200 200
With a single philosopher, there’s only one fork available. The philosopher will take one fork and wait for a second fork that never becomes available, eventually dying after time_to_die milliseconds.

Example Terminal Sessions

Successful Simulation with Meal Limit

$ ./philo 5 800 200 200 3
0 1 has taken a fork
0 1 has taken a fork
0 1 is eating
0 3 has taken a fork
0 3 has taken a fork
0 3 is eating
...
[simulation continues]
...
[simulation ends when all philosophers eat 3 times]
$

Philosopher Dies

$ ./philo 4 310 200 100
0 1 has taken a fork
0 1 has taken a fork
0 1 is eating
200 1 is sleeping
300 1 is thinking
...
410 3 died
$

Common Usage Patterns

Testing for Deadlock

Use tight timing to test if the implementation avoids deadlock:
./philo 4 410 200 200

Testing Race Conditions

Use many philosophers to stress-test thread synchronization:
./philo 200 800 200 200

Verifying Correctness

Use a small meal count to verify all philosophers get equal opportunity:
./philo 5 800 200 200 10
The program uses mutexes to protect shared resources (forks) and prevent race conditions. Output messages are also protected by a mutex to prevent interleaved text.

Build docs developers (and LLMs) love