4. Comprendre l'ordre d'acquisition des sémaphores
4.1. Un ordre commun aux deux processus
Le support associe deux sémaphores binaires aux ressources 1 et 2, tous deux initialisés à 1. Les opérations down acquièrent la disponibilité correspondante ou bloquent si elle n'est pas disponible; up permet la libération. Dans la première version, A et B suivent tous deux ce protocole :
Code (text) · sélectionner pour copier
down(ressource_1)
down(ressource_2)
utiliser les deux ressources
up(ressource_2)
up(ressource_1)
Dans cet exemple, celui qui obtient la ressource 1 peut poursuivre l'acquisition de la ressource 2. L'autre attend sur la première acquisition et ne détient pas déjà la ressource 2 à son encontre. Les deux processus ne se retrouvent pas chacun avec une première ressource différente.
Cette explication concerne le protocole et les deux ressources du support. Elle n'autorise pas à conclure que tout programme utilisant un sémaphore est automatiquement exempt d'interblocage.
4.2. Inverser deux acquisitions suffit à rendre le cycle possible
La seconde version conserve l'ordre de A, mais fait acquérir à B la ressource 2 avant la ressource 1. Un entrelacement possible devient :
| Étape | A | B |
|---|---|---|
| 1 | down(ressource_1) réussit |
— |
| 2 | — | down(ressource_2) réussit |
| 3 | down(ressource_2) bloque |
Détient encore la ressource 2 |
| 4 | Détient encore la ressource 1 | down(ressource_1) bloque |
Les deux processus restent avant leurs opérations up. Déplacer simplement une acquisition dans B a permis à chacun de conserver une ressource dont l'autre a besoin. Les sémaphores ont appliqué leur règle locale de protection; c'est l'organisation des acquisitions qui a permis la dépendance circulaire.
4.3. Ce qu'il faut expliquer dans une analyse de code
Pour justifier le problème, identifier les acquisitions qui réussissent, les acquisitions suivantes qui bloquent et les libérations devenues inaccessibles. Il faut également préciser l'initialisation des sémaphores et l'ordre interne des opérations. Écrire seulement que « les deux processus utilisent des sémaphores » ne caractérise pas le protocole fautif.
L'exemple illustre le risque d'une petite modification locale dans une grande base de code. Le maintien d'un ordre cohérent doit tenir compte de toutes les parties du programme qui partagent les ressources; un composant isolé peut ne pas rendre visible le cycle créé par leur combinaison.