elouann.dev
EN — English version

ProjetsBas-niveau & embarqué

Philosophers

Threads, mutex et data races

Période
mars 2025
Cadre
cursus 42
Équipe
solo
Note
100/100 · outstanding ×1
  • C
  • Bas-niveau
  • Algorithmes
  • Programmation impérative

Voir le code

Le dîner des philosophes : des philosophes autour d’une table, une fourchette entre chaque, et il en faut deux pour manger. Chaque philosophe est un thread, chaque fourchette un mutex, et personne ne doit mourir de faim.

la tableP1P2P3P4P51 philosophe = 1 thread1 fourchette = 1 mutexP1 mange : ses deux fourchettes sont prisesle cycle d’un threadpensefourchettesles deux, ou aucunemanget_eatdortt_sleepà chaque tour :mort, ou voisin mort ?mutex partagésaffichagemortrepas
SchémaLa table (ici avec cinq philosophes) et le cycle que suit chaque thread. Les mutex partagés protègent l’affichage et l’annonce d’une mort.

Les règles

Le programme reçoit le nombre de philosophes, le temps avant de mourir, le temps pour manger, le temps pour dormir, et éventuellement un nombre de repas. Un philosophe qui n’a pas mangé depuis trop longtemps meurt, et la simulation doit s’arrêter tout de suite, en l’affichant à la milliseconde près.

Ma solution

Chaque fourchette est une paire « mutex + valeur ». Un philosophe qui pense verrouille ses deux fourchettes, vérifie qu’elles sont libres, les marque prises, puis relâche les verrous : il ne garde jamais un mutex pendant qu’il mange, ce qui évite les interblocages.

Chaque thread suit une petite machine à états (penser, prendre les fourchettes, manger, dormir) et vérifie à chaque tour s’il a dépassé son temps ou si un voisin est mort. Le compteur de repas, l’état « vivant » et l’affichage ont chacun leur mutex : aucune donnée partagée n’est lue sans verrou.

Un peu de fantaisie

Les philosophes ont des noms, numérotés en chiffres romains, et l’affichage existe en français et en anglais, choisi à la compilation.

Ce que j’en retiens

  • Une data race ne se voit pas forcément : elle se prévient, verrou par verrou.
  • Tenir un mutex le moins longtemps possible.
  • Le temps « réel » d’un thread dépend de l’ordonnanceur, pas seulement du code.