Vous êtes sur la page 1sur 36

Chapitre 5:

Synchronisation des processus

Présenté par:
Mr Walid LOUHICHI
Dans un système multiprocessus,
l’ordonnanceur alloue le processeur à chaque
processus selon un algorithme
d’ordonnancement.
Chaque processus dispose d’un espace
d’adressage propre, indépendant et protégé
par rapport à d’autres processus.
La communication entre les processus en
échangeant des données se fait par le biais
d’une zone de mémoire partagée, par le
biais d’un fichier ou en utilisant des outils de
communication offerts par le S.E.
Une ressource désigne toute entité dont a
besoin un processus pour s’exécuter. La
ressource peut être matérielle ou logicielle.
Une ressource est caractérisé par son état
(libre ou occupée) et son nombre de points
d’accès (nombre des processus pouvant
l’utiliser en même temps).
Une ressource critique ne pouvant être
utilisée que par un seul processus à la fois.
L’utilisation d’une ressource par un processus
s’effectue en trois étapes:
L’allocation de la ressource au processus qui
consiste à donner la ressource au processus
qui la demande.
L’utilisation de la ressource.
La restitution de la ressource
L’étape de l’allocation de la ressource peut
se révéler bloquante pour le processus que
l’effectue si tous les points d’accès sont
occupés.
Au contraire, l’étape de la restitution d’une
ressource par un processus peut entrainer le
déblocage d’un autre processus en attente
d’accès à cette ressource.
Plusieurs schémas de synchronisation entre
processus ont étés définis afin de garantir
une bonne utilisation de ressources par le
processus et d’une manière générale une
communication entre processus cohérente
et sans perte de données. Ces schémas sont:
L’exclusion mutuelle
L’allocation de ressources
Les producteurs consommateurs
Les lecteurs rédacteurs
Exemple de reservation de place (avion,
train, …)
Reservation
{
If (nbreplace>0)
/* Réserver une place*/
Nbreplace--;
}
Ce programme peut s’exécuter par plusieurs
processus à la fois.
On considère l’exécution de deux processus
PClt1 et PClt2 mais le nbreplace=1.
Problème de réservation en même temps
donc nbreplace=-1;
Incohérence!!! Une place a été allouée à
deux clients différents.
La variable nbplace doit être accédée par un
seul processus à la fois pour que sa valeur
reste cohérente.
Le processus PClt1 qui a commencé la
reservation en premier doit terminer son
opération avant que le processus PClt2 puisse
commencer à s’exécuter.
Nbplace constitue une ressource critique
Le code d’utilisation d’une ressource critique
est appelé section critique.
La section critique doit au moins offrir la
propriété essentielle de l’exclusion mutuelle
qui garantit que la ressource critique
manipulée durant la section critique ne peut
effectivement être utilisée que par un seul
processus à la fois.
Pour ce faire, la section critique est
précédé par un prélude et suivi par un
postlude qui assurent cette propriété
d’exclusion mutuelle.
Plus précisément la section critique doit offrir
les trois propriétés suivantes:
L’exclusion mutuelle
Attente bornée: le processus demandant
l’accès à la section critique doit obtenir
satisfaction au bout d’un temps borné.
Bon déroulement: lorsque la section critique
est vide et qu'un ou plusieurs processus sont
en attente pour entrer dans celle-ci, le choix
du processus entrant ne révèle que des
processus en attente.
Pour garantir l’exclusion mutuelle l faut
entourer l’utilisation de la variable par un
prélude et un postlude.
Le prélude prend la forme d’une protection
qui empêche un processus de manipuler la
variable nbplace si un processus le fait déjà.
Le postlude prend la forme d’une fin de
protection qui libère la ressource nbplace et
la rend accessible aux autres processus.
Masquage et démasquage des interruptions
matérielles
Reservation
{
Disable_interrupt; /*prélude*/
If (nbplace>0)
Nbplace=nbplace-1;
Enable interrupt; :*postlude*/
}
Cette solution est moyennement satisfaisante car
elle empêche l’exécution de tous les processus
même ceux ne désirant pas accéder à la
ressource critique.
De plus le masquage et démasquage des
interruptions sont des opérations réservées
au mode superviseur et ne sont pas donc
accessibles pour les processus utilisateurs.
Ce mode de réalisation d’une section
critique est donc uniquement utilisé dans les
parties de code sensibles du SE. (file
d’attente de l’ordonnanceur, protection des
tampons du bufferde cache, …).
Test and Set est une instruction matérielle
dont l’exécution est atomique; c à d elle
s’exécute en une seule fois sans pouvoir être
interrompue. La logique est la suivante:
#define vrai 1
#define faux 0
Int function TS (int *verrou)
{
Disable interrupt;
Int test;
Test=*verrou;
*verrou= vrai;
Return (test);
Enable interrupt;
}
Exemple
/*prelude*/
While TS(cadenas)
Section critique
/*postlude*/
Cadenas =faux;
Le premier processus désirant entrer en S.C
trouve la variable cadenas = faux et la
positionne à vrai par la fonction TS
Un processus désirant entrer en SC reste en
attente active jusqu’à le repositionnement
de la variable cadenas à faux.
Cette solution ne garantit pas l’équité d’accès
à la S.C.
La solution suivante est appelé algorithme de
Peterson, c’est une solution entièrement
logicielle ne requérant aucune aide ni du
matériel ni du SE pour réaliser l’exclusion
mutuelle entre deux processus i et j.
La structure du processus i est la suivante:
/* prelude*/
While
{
Drapeau[i] = vrai ;
Tour = j;
While (Drapeau[j] && Tour == i);
Section critique
/*postlude*/
Drapeau [i] = faux;
La variable Drapeau permet à chaque
processus d’indiquer sa volonté d’entrer en
SC en positionnant celle-ci à vrai.
La variable tour indique quel processus a le
droit d’entrer en SC.
Outil de synchronisation offert par le SE.
Est une structure système composée d’une
file d’attente L de processus et d’un
compteur K, appelé niveau de sémaphore et
contenant initialement une valeur Val.
Cette structure est manipulée par trois
opérations: P(sem), V(sem) et init(sem, val) ,
qui sont indivisibles(non masquable).
Init (sem, val)
Met à vide la file d’attente L,
Initialise avec la valeur val le compteur K, un
sémaphore est assimilé à un distributeur de
jetons dont le nombre initiale est fixé par
init().
L’acquisition d’un jeton par un processus
donne le droit à ce processus de poursuivre
son exécution sinon, le processus est bloqué.
Function init (semaphore sem, int val)
{
Disable interrupt;
Sem.k= val;
Sem.L= null;
Enable interrupt;
}
P(sem)
Attribue un jeton au processus appelant s’il
en reste au moins un sinon bloque le
processus dans la file sem.L.
Function P(semaphore sem)
{
Disable interrupt;
Sem.k--;
If(sem.k<0)
{
L.Suivant = processus_courant;
Processus_courant.state=bloque;
Reordonnancement =vrai;
}
Enable interrupt;

}
V(sem)
Cette opération a pour but de rendre un
jeton au sémaphore.
S’il y a au moins un processus bloqué dans L,
alors un processus est reveillé.
La gestion des réveils est généralement en
mode FIFO.
L’opération V n’est jamais bloquante pour le
processus qui l’effectue
Function V(semaphore sem)
{
Disable interrupt;
Sem.k++;
If(sem.k<=0) /* il ya au moins un processus dans la
file*/
{
Processus_reveille = L.tete;
Processus_reveille.state=pret;
Reordonnancement =vrai;
}
Enable interrupt;

}
On utilise une sémaphore appelé Mutex avec
K=1
P(Mutex) : prélude
V(Mutex): postlude
Init (mutex, 1);
Reservation
{
P(mutex);
If(nbplace>0)
Nplace --;
V(mutex);
}
Init (Res, N)
Allocation : p(Res);
Utilisation de Res;
Restitution V( Res);
Processus P1 Processus P2
{ {
P(SR1); P(SR2);
P(SR2); P(SR1);
Utilisation de R1 et Utilisation de R1 et
R2; R2;
V(SR2); V(SR1);
V(SR1); V(SR2);
} }
Un fichier ou zone mémoire accédée
simultanément en lecture et en écriture.
Plusieurs lecteurs à la fois mais sans écriture
Une seule écriture encours.
a) Un processus rédacteur exclut tous les
autres rédacteurs ainsi que tous les
lecteurs. exclusion mutuelle avec les
autres rédacteurs et les lecteurs.
Init (Accès,1);
Rédacteur
{
P(accès);
V(accès);
}
Processus lecteur exclut les rédacteurs mais pas les autres lecteurs.
Init (mutex, 1)
lecteur
{
P(mutex);
NL++;
If (NL==1) /*premier lecteur*/
P(Accès)
V(mutex);
Acces en lecture
P(mutex)NL--;
If (NL==0)
V(acces);
V(mutex);
}

Vous aimerez peut-être aussi