/* ************************************************************************** */ /* */ /* ::: :::::::: */ /* main.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: lkantzer <lkantzer@student.42.fr> +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2025/06/14 02:52:03 by lkantzer #+# #+# */ /* Updated: 2025/09/21 06:45:51 by lkantzer ### ########.fr */ /* */ /* ************************************************************************** */
philosophers
Des threads qui mangent sans jamais se marcher dessus
Un thread par philosophe, un mutex par fourchette, un moniteur qui détecte la famine — sans accès concurrent ni interblocage.
- 1 thread / philosophe
- modèle
- 0
- accès non protégés
- 2
- implémentations
Les règles de la table
Des philosophes autour d'une table ronde, une assiette chacun, et une seule fourchette entre deux voisins. Ils ne font que trois choses, toujours dans le même ordre, et il en faut deux pour manger.
./philo nombre time_to_die time_to_eat time_to_sleep [repas à atteindre]
- Manger
- Il faut les deux fourchettes voisines en même temps. Une fourchette est un verrou : deux philosophes ne peuvent jamais tenir la même.
- Dormir
- Le repas fini, il repose ses deux fourchettes et dort le temps prévu. C'est le seul moment où ses voisins peuvent manger.
- Penser
- Puis il pense, jusqu'à retenter sa chance sur les fourchettes.
- Mourir
- S'il n'a pas commencé un repas dans les time_to_die millisecondes qui suivent le début du précédent, il meurt — et toute la simulation s'arrête à cet instant.
- S'arrêter
- La simulation s'arrête aussi, sans mort, quand chacun a atteint le nombre de repas demandé — lorsque ce dernier argument est donné.
Un philosophe seul est un cas à part : il n'a qu'une fourchette, la prend, et meurt en attendant la seconde. Le programme doit le traiter sans se bloquer.
Là où ça casse
Les règles sont simples ; les faire tenir avec un vrai thread par philosophe l'est beaucoup moins.
- Interblocage
- Si tous attrapent leur fourchette gauche au même instant, chacun attend une droite que son voisin tient. Plus personne ne mange, jamais. On l'évite en décalant les philosophes pairs au départ.
- Course
- La date du dernier repas est écrite par le philosophe et relue en continu par le moniteur. Sans un verrou dédié à cette seule date, le moniteur lit une valeur à moitié écrite et annonce une mort qui n'a pas eu lieu.
- Famine
- Éviter l'interblocage ne suffit pas : encore faut-il qu'aucun philosophe ne soit systématiquement doublé par ses deux voisins.
0 ms · 0 repas · en cours
en attente…
ce tirage, sur 20 s : 192 repas · personne ne meurt
sur 40 mises en place : aucun mort
0 ms · 0 repas · en cours
en attente…
ce tirage, sur 20 s : 5 repas · philosophe 1 mort à 1010 ms
sur 40 mises en place : 16 morts, dont 1 interblocage
- 01Chaque donnée partagée a son propre verrou, le plus fin possible
- 02Un mutex dédié protège la seule date du dernier repas
- 03Le moniteur compare en continu et arrête tout net au dépassement
- 04Deux implémentations conservées côte à côte
La granularité des verrous
Un mutex global rend la simulation triviale mais fausse. Toute la difficulté est de descendre au verrou le plus fin sans ouvrir de fenêtre de course.