La boulangerie : pourquoi la boucle \texttt{while (choisit[j
Exercice · niveau 2 · informatique (MP2I/MPI), chapitre 22 — Concurrence et synchronisation
Énoncé
} est nécessaire] Le cours affirme que « sans elle, on pourrait comparer son numéro à un ticket que est en train d'écrire ». Le montrer, et dire quelle hypothèse cache l'écriture numero[i] = 1 + maximum(numero, N).
Corrigé
L'hypothèse cachée d'abord, car tout en découle : maximum(numero, N) n'est pas une opération. C'est une boucle qui lit les cases une par une, et un autre fil peut écrire entre deux lectures. La ligne se décompose donc en opérations : lectures, puis une écriture.
Le scénario, avec deux fils. Notons .
| pas | qui | fait |
|---|---|---|
| fil | `choisit[0] = true` | |
| fil | lit puis : son maximum vaut | |
| fil | `choisit[1] = true`, lit les deux cases, maximum | |
| fil | écrit , puis `choisit[1] = false` | |
| fil | examine le fil : , donc pas de ticket : il passe | |
| fil | écrit --- le même numéro que le fil | |
| fil | entre en section critique (il a fini son examen) | |
| fil | examine : , et est faux : il passe | |
| fil | entre en section critique |
Les deux y sont. Le pas est la faute : le fil a conclu que le fil n'avait pas de ticket, alors que le fil était en train d'en prendre un. Le départage lexicographique par l'indice n'a servi à rien — il n'a été appliqué que d'un côté.
Ce que la boucle while (choisit[j]) ajoute : elle interdit au fil d'examiner le fil tant que celui-ci n'a pas fini de choisir. Le pas deviendrait une attente, et au pas les deux comparaisons porteraient sur les mêmes valeurs : le fil , d'indice plus petit, passerait, et le fil attendrait. Un seul entre.
Vérification exhaustive (problème 22.2), en modélisant la lecture du maximum case par case :
| états atteignables | exclusion mutuelle | contre-exemple | |
|---|---|---|---|
| fils, avec `choisit` | respectée | --- | |
| fils, sans `choisit` | violée | pas | |
| fils, avec `choisit` | respectée | --- | |
| fils, sans `choisit` | violée | pas |
Une première version de cette vérification traitait numero[i] = 1 + maximum(...) comme un pas atomique. Elle rendait « exclusion respectée » dans les quatre cas — c'est-à-dire qu'elle déclarait correct un protocole faux.
Un modèle trop grossier ne trouve pas le défaut : il le supprime. La leçon vaut au-delà de cet exercice : quand on vérifie du code concurrent, la première question n'est pas « le protocole est-il correct ? » mais « qu'ai-je supposé atomique ? ». Ici, la réponse est dans l'énoncé de l'exercice.
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.