5 filosofi sono seduti intorno a un tavolo, e alternano momenti in cui pensano a momenti in cui mangiano. Per mangiare, i filosofi hanno bisogno di due bacchette, ma sul tavolo ne sono disponibili solo 5: ciascun filosofo ne ha una condivisa con il filosofo alla sua destra, e una condivisa con il filosofo alla sua sinistra. Di conseguenza, mentre mangia, i filosofi alla sua destra e sinistra non possono mangiare.

Più precisamente, un filosofo attraversa ciclicamente tre stati:
Una soluzione valida deve fare si che ogni filosofo affamato riesca prima o poi a mangiare, in modo che tutti i filosofi possano continuare all'infinito ad alternare momenti in cui pensano e momenti in cui mangiano.
Nelle istanze concrete di questo problema, i "filosofi" sono processi che competono con altri per delle risorse condivise, le quali possono essere usate solo in mutua esclusione, e ogni processo deve acquisire contemporaneamente più risorse per poter lavorare.
Si usano le seguenti strutture dati:
state che tiene traccia dello stato del sistema: per ogni filosofo $P_i$, state[i] può avere valore THINKING, HUNGRY, EATINGmutex, per la mutua esclusione sull'array statesem[i] per ogni filosofo $P_i$, che serve per "dare l'ok" a $P_i$: se $P_i$ non può mangiare (perchè non ha le bacchette), allora si blocca su sem[i]
Ciascun filosofo $P_i$ esegue la procedura philosopher(i)

L'implementazione di think e eat non è rilevante per la soluzione del problema
La procedura take_forks

In mutua esclusione, dichiara che $P_i$ ha fame, e chiama la procedura test per prendere le bacchette se entrambe sono libere:

Se non sono libere entrambe le bacchette, si blocca su sem[i] (dato che non è stata eseguita la signal all'interno di test)
La procedura put_forks viene eseguita interamente in mutua esclusione

Essa: