systèmes d'exploitation - supinfo pierre dimo - 2005page 6.1 chapitre 6 : synchronisation des...

72
Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005 Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel spécifique Sémaphores Problèmes classiques de synchronisation Moniteurs

Upload: amedee-delmas

Post on 04-Apr-2015

114 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1

Chapitre 6 : Synchronisation des processus et des fils

● Introduction● La section critique● Matériel spécifique● Sémaphores● Problèmes classiques de synchronisation● Moniteurs

Page 2: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.2

Introduction

● L’accès concurrent aux données peut conduire a des résultats irrationnels

● Il faut prévoir des mécanismes pour l’exécution ordonnée des processus qui coopèrent

● Les “courses” aux ressources communes.● Macro-exemple : l'accès concomitant aux mêmes

données dans plusieurs programmes.

Page 3: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.3

Gestion du solde d'un client

Prise de commande Enregistrement de règlements

Client C

OK

Mise à jour compte (4)S = S + C

Mise à jour compte (3)S = S - R

(1)

(2)Validation du client

(2)

Enregistrer la commande

Refus

S

Page 4: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.4

Les courses

● L’utilisation de la mémoire partagée pour résoudre le problème du producteur / consommateur (ch.4) contient une possibilité de course sur la donnée count.

Page 5: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.5

Les courses

Les appels producteurs while (true) {

while (count == BUFFER_SIZE) sommeil() ; // ne rien faire, le tampon est plein

// le tampon devient disponible : on produit produit_suivant

buffer[in] = produit_suivant;in = (in + 1) % BUFFER_SIZE;count++;

}

Page 6: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.6

Les courses (suite)

Les appels consommateurwhile (true) {

while (count == 0) sommeil() ; // ne rien faire, le tampon est vide

// le tampon contient quelque chose…consommé_suivant = buffer[out];out = (out + 1) % BUFFER_SIZE;count--;// consomme l’élément consommé_suivant

}

Page 7: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.7

Les courses (suite)

● On peut programmer count++ ainsi

registre1 = count registre1 = registre1 + 1 count = registre1

● On peut programmer count-- ainsi

registre2 = count registre2 = registre2 - 1 count = registre2

● Soit maintenant la séquence suivante d’exécution concomitante des deux fils ,(count étant une variable en mémoire et R1, R2 deux registres différents) :

S0: le producteur exécute registre1 <= count //registre1 = 5S1: le producteur exécute registre1 <= register1 + 1 //registre1 = 6 S2: le consommateur exécute registre2 <= count //registre2 = 5 S3: le consommateur exécute registre2 <= registre2 - 1 //registre2 = 4 S4: le producteur exécute count <= registre1 //count = 6 S5: le consommateur exécute count <= registre2 //count = 4

Page 8: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.8

La section critique

● Une section critique du processus (ou fil) P est constituée par une séquence d’instructions qui modifient l'état de ressources communes (avec d'autres processus ou fils).

● Pour éliminer les courses, aucun processus concurrent ne doit exécuter une section critique pendant que P exécute les instructions d'une section critique (un processus concurrent est un processus qui fait appel a une ressource utilisée par P dans la section critique).

● Les critères qui régissent le fonctionnement correct de processus (ou fils) qui ont des sections critiques sont au nombre de 3 :

– Exclusion mutuelle dans le temps

– Le choix du processus qui exécutera la section critique parmi plusieurs demandeurs doit se faire seulement entre les processus concurrents (les autres processus ne participent pas au choix)

– Continuité : tous les processus doivent exécuter les sections critiques (pour éviter que certains restent en état d'attente indéfinie)

Page 9: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.9

Solution pour le cas de 2 tâches

● Les deux tâches s’appellent T0 et T1● Les instructions load, store et test sont “atomiques”● On présente 3 solutions qui utilisent la même interface ExclusionMutuelle public interface ExclusionMutuelle {

public static final int TOUR_0 = 0; public static final int TOUR_1 = 1;

public abstract void solliciteSectionCritique(int tour);

public abstract void quitteSectionCritique(int tour); }

(interface désigne en Java des objets abstraits avec méthodes et champs qui doivent être matérialisés en classes à l’aide du mot clé « implement » )

Page 10: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.10

Le programme TestAlgorithmes

Ce programme crée 2 fils utilisés pour tester les algorithmes :

public class TestAlgorithmes{

public static void main(String args[]) {

ExclusionMutuelle alg = new Algorithm_1();Thread first = new Thread( new usine("usine 0", 0, alg));Thread second = new Thread(new usine("usine 1", 1, alg));

first.start();second.start();

}}

Page 11: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.11

Le fil usinepublic class usine implements Runnable {

private String nom;private int id; // un nombre entierprivate ExclusionMutuelle mutex;

public usine(String nom, int id, ExclusionMutuelle mutex) {

this.nom = nom;this.id = id;this.mutex = mutex;

}

public void run() {

while (true) { mutex.solliciteSectionCritique(id);

Exemple.SectionCritique(nom); mutex.quitteSectionCritique(id);

Exemple.SectionNormale(nom);}

}}

Page 12: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.12

Algorithme 1

public class Algorithm_1 implements ExclusionMutuelle { private volatile int tour;

public Algorithm 1() {

tour = TOUR_0;}public void solliciteSectionCritique(int t) {

while (tour != t) // ce n’est pas mon tour….Thread.yield(); // laisse la place à un autre fil

}public void quitteSectionCritique(int t) {

tour = 1 - t; // si c’etait le tour de 1 le suivant sera 0, et inversement

} }

Page 13: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.13

Algorithme_1 - explications

● Les fils se partagent la variable entière tour. Cependant, le partage de cette variable n’est pas sans poser problème a cause des optimisations automatiques qu’un compilateur peut effectuer, comme par exemple lorsqu’il utilise le cache pour stocker une variable du programme qui ne change pas pendant plusieurs cycles d’UC (tour dans la boucle). C’est la raison de l’utilisation du qualificatif volatile

● Si tour == i, le fil i peut continuer (Exemple.SectionCritique...)● Sinon, le fil s’arrête et annonce (Thread.yield()) qu'il peut

temporairement céder l'accès à l'UC pour permettre à l’autre fil d'en prendre le contrôle.

● Problème de continuité : L’alternance des fils est stricte et obligatoire - seulement le fil pour lequel tour == i pourra entrer dans la section critique, même si l’autre fil est dans une section non-critique. Ce qui peut conduire un fil à une attente infinie...

Page 14: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.14

Algorithme_2

● On ajoute de l’information pour indiquer l’intention du fil d’entrer dans une section critique, à l’aide de 2 variables booléennes (fanions), initialisées à FAUX

● Le fil annonce son intention en changeant la valeur du fanion qui lui est associé en VRAI ; avant de pouvoir entrer dans sa section critique, l’autre fil doit avoir positionné le fanion à FAUX (annoncer l’intention de quitter la section critique).

● Le critère de la continuité n’est toujours pas satisfait : si un changement de contexte intervient après le positionnement du fanion par un fil, mais avant que ce fil entre dans la boucle While, et que le deuxième fil (qui a provoqué le changement de contexte) positionne son fanion à VRAI, chacun des 2 fils attendra l’autre…

Page 15: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.15

Algorithme_2

public class Algorithm_2 implements ExclusionMutuelle { private volatile boolean flag0, flag1;public Algorithm_2() {

flag0 = false; flag1 = false;}

public void solliciteSectionCritique(int t) { if (t == 0)

{ flag0 = true;while(flag1 == true)

Thread.yield(); }

else { flag1 = true;

while (flag0 == true)Thread.yield();

} }public void quitteSectionCritique(int t) {

if (t == 0) flag0 = false;

else flag1 = false;

}}

Page 16: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.16

Algorithme_3

● Combine les idées de 1 et 2● Satisfait-il aux critères de la section critique ?

Page 17: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.17

Algorithme_3

public class Algorithm_3 implements ExclusionMutuelle { private volatile boolean flag0;private volatile boolean flag1;private volatile int turn;public Algorithm_3() {

flag0 = false;flag1 = false;turn = TURN_0;

}

// Suite…

Page 18: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.18

Algorithme_3 (suite)

public void solliciteSectionCritique(int t) {int filno = 1 - t;turn = filno;if (t == 0) { flag0 = true;while(flag1 == true && turn == filno)

Thread.yield();}else { flag1 = true;while (flag0 == true && turn == filno)

Thread.yield();}

}

// Suite

Page 19: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.19

Algorithme_3 (suite et fin)

public void quitteSectionCritique(int t) { if (t == 0)

flag0 = false; else

flag1 = false; }

} // fin

Page 20: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.20

Spécifications matérielles destinées à la synchronisation des processus

● Mono-processeurs – désactivation des interruptions– Le code en cours (section critique) peut s’exécuter sans être interrompu– Sur les systèmes multi-processeurs la solution est inefficace, car la

désactivation et la réactivation des interruptions doit être appliquée à tous les processeurs, ce qui peut être très coûteux en temps de traitement. Dans ces systèmes il est en plus très difficile de prendre en compte des chagements de configuration (ajout de processeurs)

● Utilisation des instructions “atomiques” (indivisibles et non-interruptibles)– Instructions TAS (Test-And-Set) – Instructions CAS (Compare-And-Swap)

Ces instructions sont maintenant répandues dans les architectures multiprocesseurs car elle sont indipensables pour la réalisation de SE fiables.

● Les instructions atomiques du niveau matériel ne sont généralement pas à la portée des programmeurs d’applications.

Page 21: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.21

Simulation de l’équipement (mémoire et instructions atomiques)

public class HardwareData { private boolean data;public HardwareData(boolean data) {

this.data = data;}

// pour accéder a DATApublic boolean get() {

return data;}

public void set(boolean data) { this.data = data;

}

//Suite…

Page 22: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.22

Simulation de l’équipement (mémoire et instructions atomiques) suite

public boolean getAndSet(boolean data) {boolean oldValue = this.get();this.set(data);return oldValue;

}

public void swap(HardwareData other) { boolean temp = this.get();this.set(other.get());other.set(temp);

}

} // fin de la définition de la classe

Page 23: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.23

Fil utilisant une commande “get-and-set”

// le verrou est partagé par tous les filsHardwareData lock = new HardwareData(false);

while (true) { while (lock.getAndSet(true))

Thread.yield(); // attend la libération du verrousectioncritique();lock.set(false);sectionNonCritique();

}

Page 24: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.24

Fil utilisant une instruction “swap”

// le verrou est partagé par tous les filsHardwareData lock = new HardwareData(false);

// chaque fil possède une copie locale de la clé (key)HardwareData key = new HardwareData(true);

while (true) { // boucle infinie pour testerkey.set(true);do {

lock.swap(key);}while (key.get() == true);sectionCritique();lock.set(false);sectionNonCritique();

}

Page 25: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.25

Les Sémaphores● C’est une technique courante pour la synchronisation des

processus au niveau des programmes utilisateurs● Désavantage : le processus qui souhaite acquérir le sémaphore

doit attendre si ce dernier est déjà pris par un autre processus : spinlock

● Un sémaphore c’est une variable de type entier dont l’utilisation se réduit à 3 commandes atomiques :

– Initialisation– Acquisition (obtenir)

obtenir(S) { while S <= 0 ; // on ne fait rien, un autre processus a acquis le

//sémaphoreS--; // on déduit 1 (sémaphore pris)

}– Libération (liberer)

liberer(S) { S++; // on ajoute 1 (sémaphore libéré)

}

Page 26: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.26

Les Sémaphores comme outils de synchronisation

● Sémaphore compteur – une variable qui peut prendre n’importe quelle valeur entière

● Sémaphore binaire – une variable qui peut prendre seulement les valeurs 0 et 1

● Pour réaliser l’exclusion nécessaire en cas de sections critiques,

Semaphore S; // initialisation à 1

obtenir(S);sectioncritique();liberer(S);

Page 27: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.27

● Le désavantage principal des algorithmes de synchronisation présentés antérieurement consiste dans le fait que lorsqu’un processus est dans la section critique, tout autre processus qui veut exécuter la section critique doit attendre en bouclant, ce qui constitue une utilisation improductive de l’UC. D’autres processus pourraient l’utiliser.

● Les verrous qui agissent ainsi portent le nom de verrous tournants (spinlocks). Ils sont utiles lorsque les attentes prévues sont courtes ou dans le cas des multiprocesseurs car un fil peut s’exécuter sur un processeur différent.

Les semaphores (suite)

Page 28: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.28

● On peut éviter les verrous tournants en utilisant une queue d’attente et le blocage du fil le temps de libérer le processeur occupé par la section critique d’un autre processus. Le fil bloqué passe en état d’attente et l’ordonnanceur donne le contrôle à un autre processus.

● Le processus bloquant exécute une opération de libération du sémaphore lorsque la section critique s’est terminée et le processus bloqué est réveillé pour le passer dans la queue des processus prêts.

● Pour fonctionner ainsi, le sémaphore est construit avec une variable entière et une liste de processus.

Les semaphores (suite)

Page 29: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.29

Synchronisation à l’aide de sémaphore - usine

public class usine implements Runnable{ private Semaphore sem;private String nom;public usine(Semaphore sem, String nom) {

this.sem = sem;this.nom = nom;

}public void run() {

while (true) { sem.obtenir(); // en attente du sémaphoreMutlExUtil.sectioncritique(nom);sem.liberer();MutlExUtil.sectionNonCritique(nom);

}}

}

Page 30: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.30

Synchronisation à l’aide de sémaphore – le programme principal

public class SimulateurSemaphore { public static void main(String args[]) {

Semaphore sem = new Semaphore(1);Thread[ ] fils = new Thread[5];

for (int i = 0; i < 5; i++)fils[i] = new Thread(new usine(sem, "usine " + (new

Integer(i)).toString() ));

for (int i = 0; i < 5; i++)fils[i].start();

}

}

Page 31: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.31

Implémentation du sémaphore

obtenir(S){ value--;if (value < 0) {

ajouter ce processus à la liste d’attentebloquer ; // au lieu de boucler, ce qui permet à

l’Ordonnanceur d’en choisir un autre pour exécution.}

}

liberer(S){ value++;if (value <= 0) {

enlever un processus de la liste d’attenteréveiller(P);

}}

Page 32: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.32

Implémentation du sémaphore

Les opérations de blocage, mise en queue d’attente, réveil et remise dans la queue des processus prêts sont implémentées comme des primitives du SE.

● Doit garantir l’impossibilité que deux processus soient capables d’exécuter obtenir() et liberer() sur le même sémaphore en même temps

● L’implémentation est ainsi réduite à un problème de section critique, avec les conséquences décrites antérieurement (risques d’attentes prolongées mais facilité de réalisation)

Page 33: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.33

Blocages (Deadlock and Starvation)

● L’utilisation des sémaphores et des queues d’attente peut donner lieu à 2 situations de blocage :

● Interblocage : deux ou plusieurs processus attendent indéfiniment un évènement qu’un autre parmi eux peut seul produire (“etreinte mortelle”).

– Exemple : Soit S et Q deux sémaphores initialisés à 1

P0 P1

obtenir(S); obtenir(Q); obtenir(Q); obtenir(S);

. . liberer(S); liberer(Q); liberer(Q); liberer(S);

– Attente infinie : le processus n’est jamais enlevé de la queue d’accès au sémaphore

Page 34: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.34

Problèmes classiques de synchronisation

● Le tampon de taille finie (problème du producteur / consommateur)

● Lecture et écriture dans une base de données● Le problème des philosophes

Page 35: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.35

Le tampon de taille finie

public class BoundedBuffer implements Buffer{

private static final int BUFFER SIZE = 5; // 5 objets produits/consommés

private Object[] buffer;private int in, out;private Semaphore mutex; // assure l’exclusion mutuelle lors de l’accès au tampon

private Semaphore empty; // compteur du nombre de tampons libres

private Semaphore full; // compteur du nombre de tampons occupés

// Suite

Page 36: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.36

Le tampon de taille finie (suite)

public BoundedBuffer() { // le tampon est initialement videin = 0;out = 0;buffer = new Object[BUFFER SIZE];mutex = new Semaphore(1);empty = new Semaphore(BUFFER SIZE);full = new Semaphore(0);

}public void insert(Object item) { /* voir suite */ }

public Object remove() { /* voir suite */ }}

Page 37: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.37

Le tampon de taille finie (suite)

public void insert(Object item) { empty.obtenir();mutex.obtenir();// ajouter un élément au tamponbuffer[in] = item;in = (in + 1) % BUFFER SIZE;mutex.liberer();full.liberer();

}

Page 38: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.38

Le tampon de taille finie (suite)

public Object remove() { full.obtenir();mutex.obtenir();// enlève un élément du tamponObject item = buffer[out];out = (out + 1) % BUFFER SIZE;mutex.liberer();empty.liberer();return item;

}

Page 39: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.39

Le tampon de taille finie (suite)

import java.util.Date;public class Producer implements Runnable { // le producteur

private Buffer buffer;

public Producer(Buffer buffer) { this.buffer = buffer;

}

public void run() { Date message;while (true) {

// attendre…SleepUtilities.nap();// produit un message et ajoute au tamponmessage = new Date();buffer.insert(message);

}}

}

Page 40: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.40

Le tampon de taille finie (suite)

import java.util.Date;public class Consumer implements Runnable { // le

consommateur

private Buffer buffer;

public Consumer(Buffer buffer) { this.buffer = buffer;

}

public void run() { Date message;while (true) {

// attendre…SleepUtilities.nap();// enlève un élément du tamponmessage = (Date)buffer.remove();

}}

}

Page 41: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.41

Le tampon de taille finie (suite)

public class Factory{

public static void main(String args[]) { Buffer buffer = new BoundedBuffer();// création des fils consommateur et producteurThread producer = new Thread(new

Producer(buffer));Thread consumer = new Thread(new

Consumer(buffer));producer.start();consumer.start();

}}

Page 42: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.42

class Buffer { private static final MAX_AVAILABLE = 100; private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);

public Object getItem() throws InterruptedException { available.acquire(); // si disponibilité obtient le sémaphore, sinon bloque le threadreturn getNextAvailableItem();

} public void putItem(Object x) {

if (markAsUnused(x)) available.release(); // libère le sémaphore}

protected Object[] items = ... Les objets qu’il faut gérer de manière protégée boolean[] used = new boolean[MAX_AVAILABLE]; protected synchronized Object getNextAvailableItem() {

for (int i = 0; i < MAX_AVAILABLE; ++i) { if (!used[i]) {

used[i] = true; return items[i]; }

} return null;

// not reached }

protected synchronized boolean markAsUnused(Object item) { for (int i = 0; i < MAX_AVAILABLE; ++i) {

if (item == items[i]) { if (used[i]) { used[i] = false; return true;

} else return false; }

} return false;

} }

Page 43: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.43

Lecture et écriture dans une base de données

public class Reader implements Runnable { // la fonction “lecture”

private RWLock db;

public Reader(RWLock db) { this.db = db;

}

public void run() { while (true) {

// attendredb.obtenirReadLock();// Accès accordé// Lecturedb.libererReadLock();

}}

}

Page 44: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.44

Lecture et écriture dans une BD (suite)

public class Writer implements Runnable { // la fonction “écriture”{

private RWLock db;

public Writer(RWLock db) { this.db = db;

}

public void run() { while (true) {

db.obtenirWriteLock();// Accès accordé

// Ecritdb.libererWriteLock();

}}

}

Page 45: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.45

Lecture et écriture dans une BD (suite)

public interface RWLock

{

public abstract void obtenirReadLock();

public abstract void obtenirWriteLock();

public abstract void libererReadLock();

public abstract void libererWriteLock();

}

Page 46: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.46

Lecture et écriture dans une BD (suite)La base de données

public class Database implements RWLock { private int readerCount;private Semaphore mutex;private Semaphore db;

public Database() { readerCount = 0;mutex = new Semaphore(1);db = new Semaphore(1);

}

public int obtenirReadLock() { /* voir suite */ }public int libererReadLock() {/* voir suite */ }public void obtenirWriteLock() {/* voir suite */ }public void libererWriteLock() {/* voir suite */ }

}

Page 47: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.47

Lecture et écriture dans une BD (suite)Méthodes utilisée pour la lecture

public void obtenirReadLock() {

mutex.obtenir();++readerCount;

// le premier lecteur en cours de lectureif (readerCount == 1)

db.obtenir();mutex.liberer();

}

public void libererReadLock() {

mutex.obtenir();--readerCount;

// le dernier lecteur a terminé if (readerCount == 0)

db.liberer();mutex.liberer();

}

Page 48: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.48

Lecture et écriture dans une BD (suite)Méthodes utilisée pour l’écriture

public void obtenirWriteLock() {

db.obtenir();

}

public void libererWriteLock() {

db.liberer();

}

Page 49: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.49

Le problème des philosophes chinois

Page 50: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.50

Le problème des philosophes chinois - enoncé

● Énoncé

– 5 philosophes réfléchissent autour d’une table ronde– Chacun a devant lui un plat de riz– Entre chaque plat de riz est disposée une baguette– Pour manger, un philosophe doit utiliser 2 baguettes, mais ne peut

utiliser que celles qui se trouvent autour de son plat● Baguettes = données partagées (stick = baguette). Le

philosophe qui veut manger prend les baguettes dans l’ordre gauche -> droite

● Seulement 2 philosophes peuvent manger en même temps● Les deux philosophes qui mangent ne peuvent pas se trouver

l’un a coté de l’autre– Après avoir mangé, un philosophe pose les baguettes utilisées au

même endroit et dans le même ordre.

● Ce problème est représentatif d’une large classe de problèmes de synchronisation de processus

Page 51: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.51

Le problème des philosophes chinois (suite)

1. On numérote les baguettes et les philosophes de 0 à 4. La baguette de gauche porte le même numéro que le philosophe, celle de droite, le numéro du philosophe + 1.

2. Chaque baguette joue le rôle d’un sémaphore

3. Les philosophes essayent de prendre systématiquement les baguettes de leur gauche en premier.

4. Si le philosophe a réussi a obtenir la baguette de gauche il essaye de récupérer celle de droite.

5. Lorsque la baguette demandée est prise par un autre philosophe, celui qui la demande attend.

Page 52: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.52

Le problème des philosophes chinois (suite)

● On peut essayer de traiter le problème en représentant chaque baguette (stick) par un sémaphore :

● Semaphore baguette[] = new semaphore[5]

● Philosophe i:while (true) {

// prend la baguette de gauchebaguette[i].obtenir();// prend la baguette de droitebaguette[(i + 1) % 5].obtenir();manger();// pose la baguette de gauchebaguette[i].liberer();// pose la baguette de droitebaguette[(i + 1) % 5].liberer();reflechir(); // Réfléchit…

}

Page 53: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.53

Le problème des philosophes chinois (suite)

● La solution ne satisfait pas car elle peut conduire à un blocage : c’est le cas ou tous les philosophes décident en même temps de manger

● Pour contourner le problème on peut :– Obliger au maximum 4 philosophes de décider simultanément de

manger – Permettre à un philosophe de manger seulement si les deux

baguettes sont à sa portée, mais dans ce cas l’opération doit être réalisée de manière « atomique » (section critique).

– Utiliser une règle d’assymetrie selon laquelle : les philosophes « impairs » commencent par prendre la baguette de droite et les philosophes « pairs » commencent par prendre la baguette de gauche

● La solution ne doit pas seulement éviter le blocage, il faut également faire en sorte qu’aucun philosophe ne meurt de faim… parce qu’il n’a jamais accès aux baguettes !

Page 54: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.54

Problème des sémaphores

● Des erreurs de programmation peuvent se produire dans la logique d’acquisition ou dans le « timing » des acquisitions / libérations des sémaphores.

● Si il y a des erreurs, elle sont difficilement détectables car elles se manifestent de manière « aléatoire » (du point de vue de l’utilisateur), c.a.d. seulement lorsque sont exécutées certaines séquences qui n’ont pas un caractère régulier

Page 55: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.55

Problème des sémaphores (suite)

● Exemples d’erreurs– Inversion de l’ordre des accès aux sémaphores : plusieurs

processus peuvent exécuter leur section critique en même temps…

● smphr.liberer()● SectionCritique()● smphr.obtenir()

– Demande double du même sémaphore : blocage● smphr.obtenir()● sectioncritique()● smphr.obtenir()

– Oubli d’une des demandes (obtenir ou liberer) : tout peut arriver !

Page 56: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.56

Les moniteurs : une approche différente de la synchronisation

● Le moniteur est un module qui réalise une abstraction sécurisée de l’exécution des fils

● Dans le moniteur, un seul fil peut être actif à la fois, l’exclusion réciproque des fils est assurée par le moniteur

● Les structures internes du moniteur ne sont pas visibles de l’extérieur et aucun fil ne peut les adresser directement.

● Des varibles du type CONDITION permettent au programmeur de faire appel aux méthodes WAIT et SIGNAL du moniteur sous la forme

– X.Wait– X.Signal

L’opération Wait met en attente le fil dans une queue si la condition X est remplie jusqu’au moment ou un autre fil envoie le message Signal. Si aucun fil n’est suspendu lorsque Signal arrive, il ne se passe rien.

Pour assurer un fonctionnement sans erreurs, lorsque un processus P envoie le message Signal il quitte le Moniteur et un processus Q en attente le remplace immédiatement.

Page 57: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.57

Moniteur avec variables de condition

Queue des demandes d’accès au moniteurDonnées

partagées

Code moniteur

Opérations

Page 58: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.58

Les philosophes : solution avec moniteur.

monitor Philosophes { int[] etat = new int[5];static final int REFLECHIT = 0;static final int FAIM = 1;static final int MANGE = 2;

condition[] self = new condition[5];

// instantiation de la classe ; tous les philosophes sont en train de réfléchirpublic Philosophes {

for (int i = 0; i < 5; i++)state[i] = THINKING;

}

// Suite

Page 59: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.59

Les Philosophes – solution avec MONITEUR (suite)

● Le rôle des variables :int[] etat = new int[5]; // décrit l’état de chaque Philosophestatic final int REFLECHIT = 0; // état “en cours de réflexion”static final int FAIM = 1; // état “a faim” et veut mangerstatic final int MANGE = 2;// état “en train de manger”condition[] self = new condition[5]; // permet d’enregistrer l’état d’attente lorsque le processus ne peut pas continuer

● Notre solution impose que la personne qui mange soit entourée de personne qui ne sont pas en train de manger, c.a.d. qu’est remplie la condition :

(etat[i+4]%5 != MANGE) && (etat[i+5]/%5 != MANGE)

Page 60: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.60

Les philosophes : solution avec moniteur (suite).

public levebag(int i) { etat[i] = FAIM;test(i);if (etat[i] != MANGE)

self[i].wait;}public posebag(int i) {

etat[i] = REFLECHIT;}private test(int i) {

if ( (etat[(i + 4) % 5] != MANGE) && (etat[i] == FAIM) && (state[(i + 1) % 5] != MANGE) )

{ setat[i] = MANGE;self[i].signal;

}}

Page 61: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.61

Les philosophes : solution avec moniteur (suite).

● Avant de manger, un philosophe doit essayer de lever les baguettes (levebag). Cette méthode fait appel à le méthode test qui vérifie que les deux baguettes sont disponibles.

● Si la demande réussit, l’état du philosophe passe à MANGE (etat[i]=MANGE dans test), sinon le fil est mis en attente (self[i].wait dans levebag)

● Les opérations doivent se dérouler dans l’ordre suivant :philor.levebag(i);mange() ; // opération se déroulant sans risquephilo.posebag(i);

ou mntr est une instance de la classe PHILOSOPHES

Page 62: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.62

Méthodes spécifiques

● Méthodes spécifiques : synchronized, wait(), notify() ● Notifications multiples● Synchronization des blocs● Les Semaphores Java● Les moniteurs Java

Page 63: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.63

Le qualificatif synchronized

● Java associe à chaque objet un verrou. Lors de l’invocation des méthodes de l’objet le verrou est ignoré.

● Le verrou est activé seulement si la méthode a été déclarée « synchronized » Pour appeler une méthode synchronisée il faut “obtenir” le verrou.

● Si le verrou est possédé par un autre thread, celui qui appelle la méthode sera mis en attente, dans la queue des threads qui demandent l’accès à la méthode verrouillée (entry set).

● Le verrou est libéré lorsque le thread quitte la méthode synchronisée

● Pour la sélection du thread qui prendra le contrôle du verrou, la machine virtuelle Java (JVM) applique normalement un algorithme FIFO

Page 64: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.64

Exemple « producteur / consommateur »

Public synchronized void insert(Object o) {while (cmpt == TAILLE_TAMPON)

thread.yield();cmpt++;tampon[i] = o;i = (i + 1)%TAILLE_TAMPON;

}

Public synchronized Object enleve(){Object o;while (cmpt == 0)

thread.yield();--cmpt;o=tampon[k];k = (k+1)%TAILLE_TAMPON;return o;

}

Ces méthodes sont appliquées au tampon commun du producteur et du consommateur. Elles nous assurent qu’il n’y aura pas de « course » entre les deux pour modifier cmpt.

Page 65: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.65

Problème posé par synchronized

● La solution exposée peut conduire à une situation de blocage réciproque :

– Le consommateur « dort »– Le tampon est plein– Le producteur produit et se met en attente de consommation,

mais a trouvé le verrou disponible et en a pris le contrôle…– Le consommateur se « reveille » mais ne peut pas accéder à

l’objet, car il est verrouillé !

Page 66: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.66

Solution : les méthodes wait() et notify()● Chaque objet Java possède en plus du verrou, un ensemble appelé

wait set, destiné à contenir des instances en attente d’exécution.● Si le thread entre dans une méthode synchronisée qu’il ne peut pas

exécuter jusqu’à sa fin (cas du producteur qui se trouve devant un tampon plein), il

– va libérer le verrou acquis (en entrant dans la méthodes synchronisée),– sera mis en état « arrêté »– sera placé dans l’ensemble d’attente (le wait set),

le temps nécessaire pour que la condition qui l’a empêché de continuer soit enfin réalisée

● Le thread qui peut débloquer la situation (dans notre exemple, le consommateur), doit annoncer que le thread bloqué peut continuer.

● On utilise à cet effet la méthode notify() qui :– Extrait (au « hasard ») un thread de la liste d’attente– Déplace le thread dans la liste des processus demandeurs d’accès au

verrou (entry set)– Change l’état du thread, de bloqué en exécutable

Page 67: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.67

Producteur / conommateur : gestion du verrou

Public synchronized void insert(Object o){while (cmpt == TAILLE_TAMPON){ // le tampon est-il plein ?

try{wait(); // oui : enlève le verrou et déplace le thread -> queue d’attente

}catch (InterruptedException e){ }

}

cmpt++; // le thread peut continuer…tampon[i] = o;i = (i+1)%TAILLE_TAMPON;

notify(); // annonce la fin de la méthode synchronisée}

Page 68: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.68

Producteur / consommateur : gestion du verrou

Public synchronized Object enleve(){Object o;while (cmpt == 0){ // le tampon est-il vide ?

try {wait(); // oui : enlève le verrou et déplace le thread -> queue

d’attente}catch(InterruptedException e) { }

}

--cmpt; // le thread peut continuer…o=tampon[k];k = (k+1)%TAILLE_TAMPON;

notify(); // annonce la sortie de la méthode synchronisée

return o;}

Page 69: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.69

notifyAll()

● Plusieurs threads peuvent se trouver dans la queue d’attente pour des raisons différentes. Il devient difficile de gérer leur réactivation avec notify().

● La méthode notifyAll() permet de débloquer tous les threads de la queue d’attente pour les déplacer dans la queue d’entrée.

● La méthode notifyAll() réduit les performances mais est plus sécurisante.

Page 70: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.70

Synchronisation des blocs● Les procédures synchronisées peuvent être pénalisantes si elles sont

complexes.● Java donne la possibilité de synchroniser seulement les parties

« sensibles » du code, en utilisant un objet que l’on peut appelé Verrou, comme dans l’exemple ci-dessous :

Object Verrou = new Object();…………Public void uneMéthode() {

sectionNonCritique() ;synchronized(Verrou) {

sectionCritique()}sectionNonCritique

}

Page 71: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.71

Gestion des interruptions

● Un thread peut être interrompu par un autre thread en utilisant la méthode interrupt() ce qui positionne un fanion dans le thread interrompu, mais ne l’arrête pas : l’arrêt effectif est de la responsabilité du thread interrompu, qui doit donc tester le fanion (isInterrupted())

● La méthode wait() teste également ce fanion. Si il est « vrai », une exception est générée (le fanion est en même temps remis à « faux »).

● L’utilisation de wait() nous a obligé de prévoir la paire de blocs try{} / catch{} qui permettent de gérer les méthodes dans lesquelles il peut se produire des interruptions.

● Les interruptions ainsi générées peuvent être traitées dans le thread, mais cela n’a pas été fait dans les exemples précédents pour des raisons de clarté.

Page 72: Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.1 Chapitre 6 : Synchronisation des processus et des fils Introduction La section critique Matériel

Systèmes d'exploitation - SUPINFO Pierre Dimo - 2005Page 6.72

Quelques règles concernant la synchronisation des processus

● Un thread qui contrôle un verou d’un objet, peut entrer dans une autre méthode synchronisée et prendre le contrôle d’un autre verrou du même objet : verrouillage récursif.

● Le même thread peut contrôler des verrous appartenant à des objets différents

● Une méthode non-synchronisée peut être appelée quelle que soit l’état de l’objet auquel elle est rattachée : elle sera utilisable même si un verrou a été pris par un thread sur le même objet (c.a.d. qu’un autre thread exécute une méthode synchronisée).

● Si la queue d’attente (le wait set) d’un objet est vide, les méthodes notify() et notifyall() sont sans effet.

● Les méthodes wait(), notify() et notifyAll() peuvent être invoquées seulement à partir de méthodes synchronisées..