Chapitre 4 : Synchronisation entre processus


Les solutions matérielles

Nous pouvons distinguer dans cette catégorie plusieurs solutions. Elles s’appuient toutes sur un dispositif matériel.



Désarmement des interruptions

L'idée consiste tout simplement à ne pas allouer l’unité centrale à un autre processus tant que le processus courant dans une section critique. De cette façon, nous avons la certitude que la section critique va s’exécuter de manière indivisible.
Comme l’allocation de l’unité centrale est la conséquence à la prise en compte d’une interruption non masquée, alors il suffit pou résoudre le problème de masquer les interruptions pendant la durée de la section critique.
Les deux sections de ce protocole se définissent de la manière suivante :

Prologue (section d’entrée) : Masquer les interruptions.
Epilogue (section d’entrée) : Démasquer les interruptions.


Le comportement des processus est décrit par le schéma suivant :

while(1)
{
< Section Restante >
Masquer les interruptions ;
< Section Critique >
Démasquer les interruptions ;
}


Malgré sa simplicité, la solution précédente souffre d’un certain nombre d’inconvénients :



Test-And-Set

Cette solution est basée sur l’utilisation d’une instruction permettant de lire et d’écrire le contenu d’un mot mémoire de manière indivisible. Cette instruction s’appelle Test-And-Set (TAS).
L’action réalisée par cette instruction est donnée par le pseudo-code suivant :

Void TAS(int *a, int *b)
{
*a = *b;
*b = 1;
}


Un protocole, utilisant cette instruction, a été mis au point pour résoudre le problème de la section critique. La mise en œuvre de ce protocole nécessite l’utilisation de :


Verrou == 1 si la section critique est verrouillée, 0 sinon.

Le processus entrant dans la section critique verrouille son accès (positionner verrou à 1) tant qu’il est à l’intérieure interdisant ainsi les autres d’y entrer. A sa sortie, il déverrouille l’accès en remettant verrou à 0.

Les deux sections de ce protocole se définissent de la manière suivante :

Prologue (section d’entrée) : TAS(&testi , &Verrou)
While(testi ==1) TAS(&testi , &Verrou);

Epilogue (section d’entrée) : verrou = 0 ;


Le comportement des processus est décrit par le schéma suivant :

while(1)
{
< Section Restante >
TAS(&testi , &Verrou)
While(testi ==1) TAS(&testi , &Verrou);
< Section Critique >
verrou = 0 ;
}


La validité de cette solution est fondée sur le caractère indivisible de l’instruction TAS.

Le premier processus réussissant à exécuter (de manière indivisible) cette instruction, trouve la variable verrou à 0 et entre, par conséquent, dans sa section critique. Pendant sa présence à l’intérieur de la section critique, les processus désirant accéder à la section critique trouvent verrou == 1 et doivent ainsi attendre. En effet, cette variable n’est pas remise à 0 qu’à la sortie de la section critique. A partir de cet instant, le premier qui exécute l’instruction TAS entre à son tour dans la section critique.

L’exclusion mutuelle est assurée mais les autres conditions ne sont pas remplies :