Adloun

informatique (MP2I/MPI) · Chapitre 22 · Exercice de TD

La boulangerie : pourquoi la boucle while (choisit[j

Concurrence et synchronisation · niveau 2

É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 .

pasquifait
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 atteignablesexclusion mutuellecontre-exemple
fils, avec choisitrespectée—
fils, sans choisitviolée pas
fils, avec choisitrespectée—
fils, sans choisitviolée pas
ImportantLe grain du modèle est le contrôle

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.

Exercices semblables

Le cours du chapitre · Tous les exercices du chapitre