3. Section critique et critères de correction
Une section critique est une région de code qui lit ou modifie un état commun et qui doit être protégée contre certains entrelacements. L’objectif n’est pas d’empêcher toute concurrence, mais seulement celle qui violerait un invariant.
Une solution correcte doit satisfaire quatre propriétés :
- Exclusion mutuelle — deux participants associés au même état ne sont pas simultanément dans leur section critique.
- Progression — un participant qui demeure hors de sa section critique ne bloque pas inutilement ceux qui souhaitent entrer.
- Attente bornée — un participant intéressé finira par être admis; aucune famine ne doit être possible.
- Indépendance temporelle — la correction ne dépend ni de la vitesse relative des exécutants, ni d’un ordre d’ordonnancement, ni d’un nombre particulier de processeurs.
Ces critères permettent d’évaluer une solution par raisonnement, au lieu de conclure qu’elle est correcte parce qu’un test particulier réussit.
3.1 Désactiver les interruptions
Désactiver les interruptions empêche la préemption sur le processeur concerné. Cette méthode peut être employée dans de très courts chemins noyau contrôlés, mais elle est inadaptée à une application ordinaire :
- oublier de réactiver les interruptions peut paralyser le système;
- une application ne devrait pas contrôler globalement l’ordonnancement;
- sur une machine multiprocesseur, les autres cœurs continuent d’exécuter du code.
Elle ne constitue donc pas une primitive générale d’exclusion mutuelle en espace utilisateur.
3.2 Verrou logiciel naïf
Le schéma suivant est incorrect :
Code (c) · sélectionner pour copier
while (lock == 1) {
/* attente */
}
lock = 1;
/* section critique */
lock = 0;
Le test et l’affectation sont séparés. Si P0 réussit le test puis est interrompu avant lock = 1, P1 peut réussir le même test et entrer. Lorsque P0 reprend, il entre aussi. Donner à une variable le nom de « verrou » ne rend pas atomique son utilisation.