Probleme – Vérifier un protocole en explorant tous les entrelacements
Exercice · niveau 3 (difficile) · informatique (MP2I/MPI), chapitre 22 — Concurrence et synchronisation
Énoncé
Les exercices 22.4, 22.5 et 22.9 ont exhibé des entrelacements fatals à la main. On veut les trouver systématiquement.
- Modéliser un protocole comme un système de transitions. Qu'est-ce qu'un état ?
- Écrire l'exploration, et dire ce qu'elle cherche.
- L'appliquer à Peterson et à la boulangerie. Quel piège guette la modélisation ?
- Que ne prouve-t-elle pas ?
Corrigé
1. Le modèle. Un état est la donnée de :
- le compteur ordinal de chaque fil — à quelle ligne il en est ;
- la valeur de chaque variable partagée ;
- la valeur de chaque variable locale d'un fil, lorsqu'elle survit d'une ligne à la suivante (l'indice de boucle, le maximum en cours de calcul).
Une transition fait avancer un fil d'une ligne. Le graphe de tous les états atteignables depuis l'état initial contient, par construction, tous les entrelacements possibles — et rien d'autre.
C'est le graphe du chapitre chap:graphes, et l'exploration est celle du chapitre chap:parcours : un parcours en largeur avec un ensemble d'états visités.
2. L'exploration.
Entrée : etat_initial, une fonction successeurs, un predicat en_section
Sortie : le nombre d'etats atteignables, un contre-exemple s'il en existe
vus <-- {etat_initial}
file <-- [etat_initial]
pere[etat_initial] <-- aucun
tant que la file n'est pas vide :
e <-- defiler
si en_section(e) >= 2 : contre-exemple trouve, remonter par pere
succ <-- successeurs(e)
si aucun element de succ ne differe de e, et qu'un fil est engage :
etat d'INTERBLOCAGE
pour chaque s de succ non deja vu :
vus <-- vus + {s} ; pere[s] <-- e ; enfiler s
Elle cherche deux choses, et il faut les distinguer.
| Défaut | ce qu'on cherche dans le graphe |
|---|---|
| exclusion violée | un état où deux fils sont en section critique |
| interblocage | un état sans successeur qui le fasse changer |
| famine | un cycle évitant indéfiniment un fil demandeur |
Les deux premières sont des propriétés d'états : on les teste en visitant. La troisième est une propriété de chemins infinis, et demande une analyse des cycles du graphe — on ne la traite pas ici. Le tableau du dictionnaire pere sert à reconstituer la trace : un contre-exemple sans sa trace n'apprend rien.
3. Les résultats, tous mesurés.
| Protocole | états | exclusion | interblocages |
|---|---|---|---|
| Peterson, ordre du cours | respectée | ||
| Peterson, deux lignes échangées | violée ( pas) | ||
| Boulangerie fils, avec `choisit` | respectée | ||
| Boulangerie fils, sans `choisit` | violée ( pas) | ||
| Boulangerie fils, avec `choisit` | respectée | ||
| Boulangerie fils, sans `choisit` | violée ( pas) | ||
| Deux verrous, ordres inversés | --- | ||
| Deux verrous, ordre total | --- | ||
| Philosophes, tous à gauche | --- | ||
| Philosophes, un seul inverse | --- | ||
| Philosophes, fourchettes numérotées | --- |
Deux lectures de ce tableau valent d'être relevées.
D'abord, les deux dernières lignes ont le même nombre d'états. Ce n'est pas un hasard : avec cinq philosophes, « prendre la fourchette de plus petit numéro » revient à ce que les philosophes à prennent leur gauche et que le philosophe prenne sa droite — c'est-à-dire exactement la parade 1, appliquée à un autre convive. La mesure confirme ce que le cours annonce : « la parade 2 est la généralisation de la parade 1 ».
Ensuite, les états ne se comptent pas en millions. Deux fils, deux variables : états. C'est infime, et pourtant aucun être humain ne parcourt entrelacements sans en oublier.
Le piège de la modélisation, et il est central : qu'a-t-on supposé atomique ? Une première version de ce programme traitait numero[i] = 1 + maximum(numero, N) comme une transition unique. Elle rendait alors « boulangerie sans choisit : exclusion respectée » — déclarant correct un protocole faux. Il a fallu décomposer la lecture du maximum en transitions, une par case, pour que le défaut réapparaisse.
C'est la limite de la méthode, et elle est de la même nature que celle des tests du chapitre chap:discipline : un modèle trop grossier ne rate pas le défaut, il le supprime. Un contrôle qui déclare tout correct doit être suspecté avant d'être cru.
La règle pratique est de décomposer jusqu'aux accès mémoire : une transition doit correspondre à une lecture ou à une écriture d'une case partagée, jamais à une expression composée. Si le modèle devient trop gros, on réduit le nombre de fils — pas la finesse.
4. Ce que l'exploration ne prouve pas.
- Elle ne prouve rien pour quelconque. On a vérifié la boulangerie pour et fils ; fils demanderaient un graphe hors de portée, et fils une preuve, pas un calcul. La vérification confirme, elle ne généralise pas.
- Elle ne dit rien de l'équité. Aucun interblocage n'est signalé pour les philosophes avec la parade 2, et pourtant la mesure du problème 22.4 montrera une famine sévère.
- Elle suppose la mémoire séquentiellement cohérente : que toute écriture soit vue immédiatement par tous, dans l'ordre du programme. Aucun processeur moderne ne le garantit — c'est la mise en garde du cours sur les barrières mémoire. Peterson est correct dans ce modèle, et faux sur une machine réelle sans barrières.
La conclusion est celle du chapitre chap:discipline, transposée : un contrôle exhaustif sur un modèle est infiniment supérieur à des tests aléatoires sur le vrai programme, et il ne remplace pas la compréhension de ce qu'on a modélisé.
Les autres exercices de ce chapitre Le cours du chapitre
Un blocage sur cet exercice ? Le tuteur d'Adloun guide par questions, sans donner la réponse.