Vous êtes sur la page 1sur 37

Chapitre III

Synchronisation des processus


Partage d’informations
Les processus peuvent partager des informations de
diverses manières :
• L’échange d’informations via des fichiers.
• Les informations écrites par un processus peuvent
être lues par un autre. Le principe est valable même
pour des processus qui ne s’exécutent pas
simultanément.
• Le partage d’emplacements mémoire. C’est
essentiellement de cette manière que communiquent
les threads qui sont des "sous processus" qui partagent
un même espace d’adressage.
• Les pipes, les redirections d’E/S ou un système de
messagerie pour processus prévu par le système
d’exploitation.
Ressources d’un système informatique
Dans un système d’information, il y a deux types de ressources :
• Ressources partageables : Les ressources qui peuvent être
utilisées par plusieurs processus sans provoquer
d’interférences : le processeur, les fichiers en lecture seule et
les zones de mémoire qui ne contiennent que des
procédures ou des données protégées contre toute
modification.
• Ressources non partageables : Les ressources qui ne peuvent
être utilisées que par un seul processus à la fois ;
– soit parce qu’il est matériellement impossible de partager cette
ressource,
– soit parce qu’elle contient des données susceptibles d’être
modifiées.
– Le résultat est imprévisible si pendant qu’un processus lit une
donnée, un autre la modifie.
Synchronisation de processus
• Un système d'exploitation dispose de
ressources (imprimantes, disques, mémoire,
fichiers, base de données, ...), que les
processus peuvent vouloir partager.
• Ils sont alors en situation de concurrence
(race) vis-à-vis des ressources.
Exemple de conflit d’accès
• Prenons l’exemple de l’enregistrement de
travaux d’impression dans un spooler
d’Andrew Tanenbaum.
• L’imprimante est une ressource qui ne
peut pas être utilisée simultanément par
plusieurs processus. Les travaux d’impression
doivent donc être enregistrés dans un
répertoire de spool en attendant d’être
imprimés.
Exemple de conflit d’accès
• Les processus qui veulent imprimer ont accès à
deux variables partagées In et Out associées au
spooler :
– In le numéro à attribuer au prochain fichier qui entre
dans le spooler
– Out le numéro du prochain fichier à imprimer.
• Un processus qui décide de placer un fichier dans
le répertoire de spool, doit lire la variable In, se
servir de cette valeur pour inscrire à l’endroit
voulu le fichier à imprimer, puis modifier la
variable In pour lui faire indiquer l’emplacement
libre suivant.
Exemple de conflit d’accès
Exemple de conflit d’accès
• Imaginons que deux processus (A et B)
entreprennent presque simultanément d’envoyer un
document à l’impression.
• Si le processus A est interrompu pendant
l’exécution de la section critique pour
qu’entretemps l’ordonnanceur passe la main au
processus B, la variable In sera relue par B et
réutilisée une deuxième fois consécutivement avant
d’avoir été incrémentée par le processus A.
• Les deux processus vont donc inscrire le fichier à
imprimer au même emplacement du spool et, bien
que l’état du répertoire de spooler semble
cohérent, un des deux fichiers ne sera jamais
imprimé.
Exemple de conflit d’accès

Pour éviter ces conflits d’accès, il faut empêcher la lecture ou


l’écriture de données partagées à plus d’un processus à la fois. La
solution est l’exclusion mutuelle pour les accès concurrents.
• Il faut synchroniser les actions sur les ressources
partagées.
• Le code exécuté par un processus a des parties
qui ont besoin d’accéder aux ressources
partagées : ce sont les sections critiques
• Dans l’exemple ci-dessus, les instructions qui se
situent entre le moment où on lit la variable
partagée In et le moment où cette variable est
modifiée forment une section critique.
• La synchronisation des processus concerne les
processus parallèles qui utilisent des ressources
ou données non partageables.
Section critique
• C’est la partie de programme dans laquelle se
font des accès à une ressource partagée
• Dans la plupart des cas, l'accès à cette section
critique devra se faire en exclusion mutuelle,
ce qui implique de rendre indivisible ou
atomique la séquence d'instructions
composant la section critique.
• Exemple : accès à une base de données.
– Plusieurs processus peuvent la lire simultanément,
mais quand un processus la met à jour, tous les
autres accès doivent être interdits.
Conditions d'accès à une section critique
• exclusion mutuelle pour l’accès à la section
critique : deux processus ne peuvent être
ensemble en section critique,
• pas d'interblocage : un processus bloqué en
dehors de sa section critique ne doit pas
empêcher un autre d'entrer dans la sienne,
• pas d'attente infinie pour entrer dans la
section critique : Si deux processus attendent
l'entrée dans leurs sections critiques
respectives, le choix doit se faire en un temps
fini
Conditions d'accès à une section critique
• accès équitable : tous les processus doivent
avoir la même chance d'entrer en section
critique, pas d'hypothèses sur les vitesses
relatives des processus (indépendance vis à vis
du matériel).
Outils de synchronisation
• Matériels :
– emploi d'une instruction de type Test and Set qui teste
l'état d'une case mémoire commune aux deux
processus et change sa valeur,
– inhibition des interruptions (possible seulement dans
le cas d'un processus se déroulant en mode privilégié).
• Logiciels :
– Wait & Signal
– sémaphores (outils logiciels mis à la disposition des
utilisateurs par le système d'exploitation),
– algorithmes de synchronisation.
Propriétés des outils de synchronisation
• sûreté (safety) : deux processus ne doivent pas se
trouver ensemble en section critique. Il faudra
assurer l’exclusion mutuelle.
• vivacité (liveness), impose des contraintes de :
– progression : il faudra éviter l’inter-blocage,
– équité : pas de famine,
– attente bornée.
– Toute demande sera satisfaite, ou encore : tout
processus qui veut entrer en section critique devra
pouvoir le faire
• Les algorithmes de synchronisation sont des
compromis entre sûreté et vivacité.
TestAndSet (TAS)
• TAS : une instruction du langage machine
• TAS est insécable. Lorsque le processeur
commence l'exécution d'une instruction du
langage machine, il va jusqu'au bout même si
une interruption arrive.
• TAS permet de synchroniser des activités en
environnement multiprocesseur.
TestAndSet (TAS)
• Cette instruction exécute une succession
ininterruptible de deux opérations : tester &
verrouiller. Ou Test & set
• L’instruction TAS fait référence à une
variable partagée. Appelons la Lock.
• Lorsque cette variable est à 0, n’importe
quel processus peut, via l’instruction TAS,
la mettre à 1 « Set Lock » puis entrer dans la
section critique.
TestAndSet (TAS)
Les inconvénients du TestAndSet
• l'attente active (busy waiting) : un processus qui
trouve la variable de synchronisation à 1
continuera à la tester jusqu'à ce qu'elle passe à 0.
Il reste donc actif, alors qu'il pourrait être
suspendu et rangé dans une file d'attente.
• le fait qu'on ne sait pas qui va prendre la main. Ce
problème est lié au précédent. En effet, puisqu'il
n'y a pas de gestion de la file des processus en
attente sur le passage de la variable à 0, le
premier qui obtient une réponse satisfaisante au
test entre dans sa section critique. Ce n'est pas
forcément celui qui attendait depuis le plus
longtemps.
Inhibition des interruptions
• Nous savons que dans un système
monoprocesseur c’est un ordonnanceur qui
tour à tour passe la main à chaque processus
pour donner une impression de parallélisme.
• Il est possible d’éviter l’intervention de
l’ordonnanceur dans une section critique en
s’interdisant d’exécuter des instructions
susceptibles de provoquer le déroutement
et en désactivant momentanément les
interruptions.
Inhibition des interruptions
• Un processus peut empêcher le SE de s’exécuter
– en n’éméttant pas d’instruction d’appel au superviseur,
– en exécutant aucune instruction susceptible de provoquer
un déroutement ou
– en désactivant les interruptions.
• L’exclusion mutuelle peut être réalisée à travers la
mise en œuvre de primitives du SE afin qu’elles
désactivent et activent les interruptions. L’accès à la
section critique peut être contrôlée en appelant ces
primitives
Inhibition des interruptions
DisactiverInterruption()
//section critique
ActiverInterruption()
• Le processus qui entre dans la section critique
monopolise ainsi le processeur en excluant tout autre
processus.
• Ce mécanisme est facile à mettre en œuvre
• Mais il ne fonctionne que sur un SE mono-cpu
• Perte de certaines interruptions
• Risque de famine
Wait & Signal
• Les SE fournissent des primitives Wait & Signal
leur permettant de mettre en œuvre la
solution de TestAndSet avec des attentes non
actives
• Un objet ProcessQueue avec les opérations
Insert et remove
– Insert place un objet au bout de la file et change
l’état du processus en bloqué
– Remove sélectionne le processus qui se trouve
dans la file depuis longtemps et change son état
de bloqué en prêt.
Wait & Signal
Struct waitSignalVar {
boolean lock
Processqueue queue
}
Void wait(WaitSignalVar var)
{if(TestAndSet(var.lock)
var.queue.Insert(); }

Void signal(WaitSignalVar var)


{ var.queue.Remove();
var.lock=false; }
Sémaphore
• Le sémaphore est en quelque sorte un
distributeur de jetons d’accès à la ressource.
• Le nombre de jetons pouvant être distribués
dépend du nombre de processus qui peuvent
accéder en même temps à la ressource.
• Le nombre de jetons est fixe. Il est initialisé lors
de la création du sémaphore.
• Chaque processus, pour avoir le droit d’accéder
à la ressource, doit emprunter un jeton qu’il
rend après utilisation.
• Le sémaphore est donc une variable entière dont
la valeur positive est fixée lors de sa création et
qui n’admet par la suite que deux opérations P(s)
et V(s) du néerlandais (Proberen = essayer et
Verhogen = incrémenter).
• Synonymes de P / V: Down() / Up() Wait() /
Signal()
Sémaphore
• Un sémaphore S associé à une ressource R est un
objet composé :
– d'un compteur S.compt qui indique le nombre
d'éléments disponibles ou le nombre de processus
possible sur R,
– d'une file d'attente S.FA où sont chaînés les processus
en attente sur la ressource R.
• Un sémaphore binaire ou mutex est un
sémaphore dont le compteur ne peut prendre
que deux valeurs positives possibles : en générale
1 et 0.
Opérations sur un sémaphore
• Ce sont des opérations atomiques
• Init(S, val) qui initialise le nombre d’éléments de
ressource val : S.compt = val et S.FA = vide.
• P (Passeren) pour demander un élément de la
ressource.
– L’opération P(s) décrémente la valeur du niveau de
sémaphore si elle est supérieure à 0 (s’il y a des jetons
disponibles). Quand la décrémentation est impossible le
processus est bloqué et attend dans la file d’attente V
(Vrijgeven).
– V(S) libère un élément de la ressource. On incrémente
S.compt. Si S.compt ≤ 0 alors on sort un processus de S.FA,
il passe dans la file des prêts et on peut lui allouer un
élément de ressource.
Verrou
• Le verrou (lock) est un mécanisme destiné à mettre en
œuvre l’exclusion mutuelle.
• C’est un objet système auquel sont associées deux
opérations systèmes, verrouiller et déverrouiller.
– Verrouiller est l’opération qui permet à un processus
d’acquérir la ressource si elle est disponible. Dans le cas
contraire, le processus passe dans l’état bloqué en
attendant la ressource.
– Déverrouiller est l’opération système par laquelle le
processus libère la ressource qu’il monopolisait.
• Ces opérations aussi appelées primitives système sont
des opérations indivisibles. Le système d’exploitation
garantit qu’elles ne pourraient être interrompues par
d’autres processus.
Algorithmes de synchronisation
• Algorithme de Dekker
• Algorithme de Peterson
• Algorithme du boulanger
• Limitations :
– On suppose que les opérations de lecture,
d’écriture et de test d’un mot en mémoire sont
atomiques.
Algorithme de Dekker
• Proposé par Theodorus Dekker.
• Un algorithme d'exclusion mutuelle permettant la
synchronisation de deux processus partageant une
zone de mémoire.
• basé sur une approche par attente active et est divisé
en deux parties, à savoir le protocole d'entrée dans
la section critique et le protocole de sortie
• Chaque processus est identifié par un numéro unique.
Ces identificateurs doivent être contigus.
• Le nombre maximum de thread doit être connu à
l'avance.
• Cet algorithme nous affranchit de tout risque
de famine, mais cela est coûteux,
Algorithme de Peterson
• Publié par Gary Peterson en 1981.
• Un algorithme d'exclusion mutuelle pour
la programmation concurrente.
• Cet algorithme est basé sur une approche
par attente active.
• Il est constitué de deux parties : le protocole
d'entrée dans la section critique et le
protocole de sortie.
Quelques problèmes classiques de
synchronisation
• Producteur et consommateur
• Banquier
• Écrivain et lecteur
Producteur et consommateur
• Un producteur et un consommateur se
partage la ressource « tampon »
• Un producteur dépose des messages dans un
tampon ;
• un consommateur retire ces messages du
tampon.
• Le producteur et le consommateur doivent
synchroniser leurs actions.
• Les deux doivent être en situation de
coopération.
Producteur et consommateur
• 2 sémaphores sont utilisés :
– S1 indique les ressources disponibles pour le
producteur (nombre de cases vides),
– S2 indique les ressources disponibles pour le
consommateur (nombre de cases pleines).
Producteur et consommateur
• Producteur • Consommateur
P(S1) P(S2)
… …
lire (case(i))
écrire (case(i))
i:=suiv_cons(i)
i:=suiv_prod(i) …
…. V(S1)
V(S2)
Fin

Vous aimerez peut-être aussi