5. Blocage, réveil perdu et producteur-consommateur
5.1 Tampon borné
Le patron producteur-consommateur comprend :
- une file de capacité
N; - un compteur
count; - un producteur qui ajoute des éléments;
- un consommateur qui les retire.
Le producteur doit attendre lorsque la file est pleine; le consommateur doit attendre lorsqu’elle est vide. Ils doivent aussi s’exclure pendant la modification de la structure.
5.2 Pourquoi sleep/wakeup ne suffit pas
La solution naïve endort le consommateur lorsque count == 0 et le réveille après une production. Une course subsiste :
- le consommateur lit
count == 0; - il est interrompu avant
sleep; - le producteur ajoute un élément et appelle
wakeup; - le réveil est perdu, car le consommateur ne dort pas encore;
- le consommateur reprend et s’endort malgré la présence d’un élément.
Le problème est encore une séquence « vérifier puis agir » non atomique. Une primitive correcte doit réunir le test, la modification d’état et le blocage, ou mémoriser la permission à consommer.
Deux colonnes comparent des traces possibles, pas des durées. À gauche : C constate count=0, est interrompu avant sleep; P insère un élément, count=1 et wakeup ne trouve aucun dormeur; C reprend et dort malgré l’élément présent. À droite : full est initialisé à 0; P insère et fait post avant le wait de C; la permission disponible vaut 1 puis C la consomme par wait, retire sous protection distincte et full finit à 0. Un producteur, un consommateur, une production, appels réussis, aucun autre réveil ni annulation. Les traits ordonnent les étapes de chaque trace; aucun ordre général entre threads n’est promis. Le sémaphore mémorise une permission, sans remplacer le mutex du tampon. La condition n’est pas dessinée comme un compteur : elle exige un prédicat sous mutex, une attente atomique et un retest.
Source : 05 - Concurrence/SOMMAIRE_MAITRE_SEMAINE_05.md · §5.2, §6.1–6.3 et §8; schéma original du portail, relu le 15 octobre 2026.