Vous êtes sur la page 1sur 36

Chapitre 3 :

Synchronisation des processus


Threads

Plan

 La notion des threads

 Communication entre threads

 Synchronisation

• Verou

• Semaphore

• Moniteur

2
Plan

 La notion des threads

 Communication entre threads

 Synchronisation

• Verou

• Semaphore

• Moniteur

 De nombreux systèmes d’exploitation modernes offrent la possibilité


d’associer à un même processus plusieurs chemins d’exécution
(multithreading, multiflot d’exécution).

 Un thread (ou fil d’exécution en français) est une parie du code d’un programme
(une fonction), qui se déroule parallèlement à d’autre parties du programme.

4
 Un thread est une unité d’exécution rattachée à un processus, chargée
d’exécuter une partie du processus.

 Un processus est vu comme étant un ensemble de ressources (espace


d’adressage, fichiers, périphériques...) que ses threads (flots de contrôle ou
processus légers) partagent.

 Lorsqu’un processus est créé, un seul flot d’exécution (thread) est associé au
processus. Ce thread peut en créer d’autres. Chaque thread a :
• un identificateur unique
• une pile d'exécution
• des registres (un compteur ordinal)
• un état...

 Le multithreading permet l’exécution


simultanée ou en pseudo‐parallèle de
plusieurs parties d’un même processus.

 Pourquoi utiliser les threads:


• Améliorer la rapidité des applications (pas de blocages pour des tâches
qui peuvent être effectuée en parallèle)

• Exploiter de manière efficace les machines multiprocesseur

• Améliorer la structure de votre programme

 Le premier intérêt peut être d’effectuer un calcul qui dure un peu de temps
(plusieurs secondes, minutes, ou heures) sans que l’interface soit bloquée (le
programme continue à répondre aux signaux).
• Le processus MS-Word implique plusieurs threads: interaction avec le clavier,
rangement de caractères sur la page, sauvegarde régulière du travail fait
• contrôle orthographe, etc

 Les fonctions liées aux thread sont dans la bibliothèque pthread.h


• Pour créer un thread, il faut créer une fonction qui va s’exécuter dans le
thread, qui a pour prototype : void *ma_fonction_thread(void *arg);
• Dans cette fonction, on met le code qui doit être exécuté dans le thread.

6
 Création des threads: crée un processus léger qui exécute la fonction fonction avec
 l'argument arg et les attributs attr, renvoie 0 si l’appel réussit, sinon renvoie
l’identifiant de l’erreur

o pthread_t *p_tid : ID du thread


o const pthread_attr_t *attr : les attributs du thread (taille de la pile,
priorité....) , Null par défaut
o void*(*fonction)(void *) : La fonction à exécuter
o void *arg : liste des paramètres qui seront transmis a la fonction au
lancement du thread
 La commande de compilation devient :

 Terminaison d’un thread


• Le thread appelant se termine avec une valeur de retour égale a *p_status
• Ce code de retour est accessible par les autres threads à travers la fonction
pthread_join()

8
 Exemple de création des threads (creation1.c)

 Exemple de création des threads (creation.c)

10
 Exemple : partage des variables

11

 Exemple: passage des variables

12
 Passage des paramètres: crée un thread qui dort un nombre de secondes passé en
argument, pendant que le thread principal attend qu’il se termine.

13

 Passage des paramètres: crée un thread qui lit une valeur entière et la retourne au
main

14
 Comparaison des identifiants de threads
• La fonction retourne 0 si tid1 = tid2
• Une valeur non-nulle sinon

 Terminaison d’un thread: termine l’exécution la thread courante avec une valeur
de retour particulière
• Le thread appelant se termine avec une valeur de retour égale a *p_status
• Ce code de retour est accessible par les autres threads a travers la fonction
pthread_join()

 Avoir le TID d’un thread : pthread_t pthread_self(void);

15

Plan

 La notion des threads

 Communication entre threads

 Synchronisation

• Verou

• Semaphore

• Moniteur

16
 Communication entre les threads: synchronisation sur la terminaison

• Permet a un thread d’attendre la terminaison du thread tid et de récupérer une


valeur de retour correspondant a sa terminaison
• L’appel est bloquant, jusqu’` ce que le thread tid exécute pthread_exit() ou
qu’un autre thread ait demandé son abandon
• Si le thread tid est déjà terminé, le retour est immédiat et **status contient le
code de retour
• Le résultat est 0 en cas de réussite, un code d’erreur non-nul sinon

 Le thread principal crée deux threads A et


B et attend la fin de leurs exécutions. Un de
ces threads crée lui-même un thread C qu´il
attendra avant de terminer.

17

 Exemple: Synchronisation sur la terminaison

18
 Exemple: addition de deux matrices

19

 Exercice: multiplication de deux matrices (voir TD4)

• création de N fils
• chaque fil résout 1/N de la matrice C
• attendons la fin des N fils
• la matrice C peut maintenant être
utilisée

20
 Dans un programme qui utilise les threads qui ne sont pas complètement
indépendants, ils doivent communiquer entre eux (com.c)

 Non seulement la valeur attendue


n’est pas atteinte, mais en plus la
valeur change d’une exécution du
programme à la suivante.
 Problème de la section critique ou
exclusion mutuelle

21

Plan

 La notion des threads

 Communication entre threads

 Synchronisation

• Verou

• Semaphore

• Moniteur

22
 Plusieurs processus s’exécutent en pseudo-parallèle ou en parallèle et partagent
des objets (mémoires, imprimantes, etc.).
 Le partage d’objets sans précaution particulière peut conduire à des résultats
imprévisibles. L’état final dépend de l’ordonnancement des processus.
 La solution au problème s’appelle synchronisation des processus.
• Il faut empêcher les autres processus d’accéder à un objet partagé si un objet
est en train d’être utilisé par un processus, ce qu’on appelle d’assurer
l’exclusion mutuelle.
• Les situations de ce type, où deux ou plusieurs processus lisent ou écrivent
des données partagées et où le résultat dépend de l’ordonnancement des
processus, sont qualifiées d’accès concurrents.

23

 Objet critique : Objet qui ne peut être accédé simultanément, les imprimantes, la
mémoire, les fichiers, les variables etc
 Section critique : Ensemble de suites d’instructions qui opèrent sur un ou
plusieurs objets critiques et qui peuvent produire des résultats imprévisibles
lorsqu’elles sont exécutées simultanément par des processus différents, i.e., une
séquence d’instructions qui ne peuvent jamais être exécutées par plusieurs threads
simultanément
 Somme des premiers nombres en utilisant des processus légers:
• si plusieurs processus exécutent concurremment ce code, on peut obtenir un
résultat incorrect.
• La solution correcte nécessite l’utilisation des sections critiques.

24
 Les processus qui exécutent des sections critiques sont structurés comme suit:
• Section non critique.
• Demande d’entrée en section critique.
• Section critique.
• Demande de sortie de la section critique.
• Section non critique.

 Conditions sont nécessaires pour réaliser correctement une exclusion mutuelle:


• Deux processus ne peuvent être en même temps en section critique.
• Aucune hypothèse ne doit être faite sur les vitesses relatives des processus et
sur le nombre de processeurs.
• Aucun processus suspendu en dehors d’une section critique ne doit bloquer
les autres processus.
• Aucun processus ne doit attendre trop longtemps avant d’entrer en section
critique.

 Comment assurer alors une coopération correcte et efficace des processus.

 La bibliothèque POSIX fournit des moyens d’assurer l’exclusion mutuelle,


mutex (verrous), et sémaphores

25

 Verrou: les variables de verrouillage


• réalisation de l’exclusion mutuelle
• aussi nommé mutex

 Sémaphore
• gestion de jetons (compteur)
• associé à une file d’attente
• exemple : accès multiples (mais bornés) à une ressource

• Moniteur

26
Plan

 La notion des threads

 Communication entre threads

 Synchronisation

• Verou

• Semaphore

• Moniteur

27

 Utiliser une variable de verrouillage partagée verrou, unique, initialisée à 0. Pour


rentrer en section critique (voir algorithme de verrouillage), un processus doit
tester la valeur du verrou
• Si elle est égale à 0, le processus modifie la valeur du verrou à 1 et exécute sa
section critique, à la fin de la section critique, il remet le verrou à 0
• Sinon, il attend que le verrou devienne égal à 0, c’est-à-dire : while(verrou
!=0)

 Primitives pour l’utilisation de verrous


• Création / initialisation / destruction
• Verrouillage: devenir propriétaire, bloquant
• Déverrouillage: verrou devient libre

28
 Le mécanisme mutex (MUTual EXclusion ) repose sur l’utilisation du type
pthread_mutex_t

 Un mutex est une structure de données qui permet de contrôler l’accès à une
ressource. Un mécanisme empêchant deux processus ou plus d'accéder simultanément
à une ressource partagée.

 Sur les voies ferrées:


o un sémaphore empêche deux trains d'entrer en collision sur un tronçon de voie
commune.
o Sur les voies ferrées comme dans les ordinateurs, les sémaphores ne sont
qu'indicatifs : si un machiniste ne voit pas le signal ou ne s'y conforme pas, le
sémaphore ne pourra éviter la collision.

29

 Le mécanisme mutex (MUTual EXclusion ) repose sur l’utilisation du type


pthread_mutex_t

 Un mutex est une structure de données qui permet de contrôler l’accès à une
ressource. Un mécanisme empêchant deux processus ou plus d'accéder simultanément
à une ressource partagée.

 Un mutex qui contrôle une ressource peut se trouver dans deux états :
• Libre (ou unlocked). Cet état indique que la ressource est libre et peut être
utilisée sans risquer de provoquer une violation d’exclusion mutuelle.
• Réservée (ou locked). Cet état indique que la ressource associée est actuellement
utilisée et qu’elle ne peut pas être utilisée par un autre thread.

 Les fonctions
• Initialisation: phtread_mutex_t mutex = THTREAD_MUTEX_INITIALIZER;
• Verrouillage: int phtread_mutex_lock(phtread_mutex_t * mutex);
• Déverrouillage: int phtread_mutex_unlock(phtread_mutex_t * mutex);
• Destruction: int pthread_mutex_destroy(pthread_mutex_t * mutex);

30
 Un mutex peut être vu comme étant une structure de données qui contient deux
informations :
• La valeur actuelle du mutex ( locked ou unlocked)
• Une queue contenant l’ensemble des threads qui sont bloqués en attente du
mutex

lock(mutex m) { unlock(mutex m) {
if(m.val==unlocked) if(m.queue is empty)
{ {
m.val=locked; m.val=unlocked;
} }
else else
{ {
// Place this thread in m.queue; // Remove one thread(T) from m.queue;
// This thread is blocked; // Mark Thread(T) as ready to run;
} }
} }

31

 Exemple: counter (counter.c) avec deux threads

 Problème de synchronisation

32
 Exemple: counter (counter1.c) avec deux threads

33

 Exercice 1 (TD4): écrire un programme permettant d’additionner N nombres, mais


en forme parallèle avec deux threads

 Exemple avec deux thread T1 et T2

34
 Exercice 2
• Soit un tableau M de N éléments rempli par un thread lent et lu par un autre
plus rapide.
• Le thread de lecture doit attendre la fin du remplissage du tableau avant
d’afficher son contenu. Qui ce que vous remarquez. Comment résoudre ce
problème.

35

 Exercice 2 (LectureEcritureTab.c)

36
 Exercice 2

37

 Le problème de l’exclusion mutuelle considère le cas de plusieurs threads qui se


partagent une ressource commune qui doit être manipulée de façon exclusive.

 Il est souvent nécessaire de coordonner l’accès de plusieurs threads à plusieurs


ressources, chacune de ces ressources devant être utilisée de façon exclusive.

 Cette utilisation de plusieurs ressources simultanément peut poser des difficultés.

 Exemple: le problème des philosophes.

 Cinq philosophes sont assis autour d’une table. Sur la table, il y a alternativement
cinq plats de spaghettis et cinq fourchettes:
• Un philosophe passe son temps à manger et à penser.

• Pour manger son plat de spaghettis, un philosophe a besoin de deux


fourchettes, une qui se trouve à sa gauche et l’autre qui se trouve à sa droite.

• Problème: chaque philosophe permet de se livrer à ses activités (penser et


manger) sans jamais être bloqué.

38
 Il est important de signaler que si tous les philosophes prennent en même temps
chacun une fourchette, aucun d’entre eux ne pourra prendre l’autre fourchette
(situation d’interblocage).

 Pour éviter cette situation, un philosophe ne prend jamais une seule fourchette. Les
fourchettes sont les objets partagés.

 L’accès et l’utilisation d’une fourchette doit se faire en exclusion mutuelle.

 Ce problème peut se modéliser en utilisant un programme C avec les threads POSIX.

• Chaque fourchette est une ressource partagée qui ne peut être utilisée que par un
philosophe à la fois.

• Chaque philosophe est modélisé par un thread.

 Écrire un programme qui permette à chaque philosophe de se livrer à ses activités


(penser et manger) sans jamais être bloqué

39

 Quand un philosophe affamé a ses deux couverts dans les mains en même temps, il
mange sans libérer ses couverts.

 Dans le cas contraire, il doit attendre que ceux-ci deviennent libres.

 Par exemple, dans notre hypothèse d'un dîner de cinq philosophes, seulement deux
philosophes peuvent manger à un instant donné car les couverts ne sont pas suffisants.

 Trois philosophes n'ont la possibilité que de penser ou d'être en attente de vouloir manger.

40
 Scénario 1:
 Les philosophes décident de manger au
même moment:
o Commencent tous par récupérer la
fourchette se trouvant à leur gauche
(resp. droite).
o Sont bloqués en essayant de récupérer
la fourchette à droite (resp. gauche)
(alors qu’il n’y a plus de fourchette sur
la table).

41

 Scénarios 1

42
 Scénarios 1

43

 Scenario 2: forçant les threads à s’approprier les mutex qu’ils utilisent dans le même
ordre
• Ph0: s’approprie d’abord le mutex fourchette[0] et ensuite le mutex fourchette[1]
• Ph1: s’approprie d’abord le mutex fourchette[1] et ensuite le mutex fourchette[2]
• Ph2: s’approprie d’abord le mutex fourchette[2] et ensuite le mutex fourchette[3]
• Ph2: s’approprie d’abord le mutex fourchette[3] et ensuite le mutex fourchette[4]
• Ph4: s’approprie d’abord le mutex fourchette[4] et ensuite le mutex fourchette[0]

 Avec cet ordre d’allocation des mutex, un deadlock n’est plus possible

 Il y aura toujours au moins un philosophe qui pourra s’approprier les deux baguettes dont
il a besoin pour manger.

 Un deadlock ne pourrait survenir que si tous les philosophes cherchent à manger


simultanément.

 Si un des philosophes ne cherche pas à manger, ses deux baguettes sont nécessairement
libres et au moins un de ses voisins philosophes pourra manger.

44
 Scenario 2:

45

 Scenario 2:

 Cette solution résout le problème d’interblocage. Mais, un philosophe peut


mourir de faim car il ne pourra jamais obtenir les fourchettes nécessaires
pour manger!!!

46
Plan

 La notion des threads

 Communication entre threads

 Synchronisation

• Verou

• Semaphore

• Moniteur

47

 La concurrence entre les processus peut être traité par l’emploi de sémaphores.

 Un sémaphore est un compteur entier qui désigne le nombre d’autorisations


d’accès à une section critique. Il a un nom et une valeur initiale, par exemple
semaphore S = 10

 Un sémaphore joue donc le rôle d'un distributeur de tickets, qui, initialement


dispose d'un certain nombre de tickets

 Les sémaphores sont manipulés au moyen des opérations P ou wait et V ou signal


• L’opération P(S) (P(uis-je) accéder à une ressource) décrémente la valeur du
sémaphore S
• L’opération V(S) (V(as-y) la ressource est disponible) incrémente la valeur du
sémaphore S

 Les sémaphores permettent de réaliser des exclusions mutuelles

48
 Principalement, un processus utilisateur du sémaphore demande un ticket en
invoquant P :
• si au moins un ticket est disponible, le processus appelant le prend et poursuit
son exécution
• sinon, le demandeur est enregistré dans une file d'attente et est bloqué dans
l'attente de l'obtention d'un ticket, l'opération P n'est exécutable par le
processus appelant que s'il existe un ticket libre

 Grace a V, si des processus sont en attente dans la file du sémaphore, le premier


d'entre eux est débloqué et obtient son ticket.

 Le problème de l'exclusion mutuelle peut être simplement résolu à l'aide d'un


sémaphore dont la valeur initiale est fixée à 1. Un tel sémaphore est couramment
appelé sémaphore d'exclusion mutuelle (mutex).

49

 Un sémaphore peut donc être représenté par un compteur, et une file d'attente de
processus. La file d'attente enregistre les processus demandeurs bloqués, et le
compteur représente :
• quand il est supérieur à 0, le nombre de tickets disponibles et donc le
nombre de processus dont les demandes seront immédiatement
satisfaisantes,
• quand il devient négatif, sa valeur absolue est alors le nombre de processus
bloqués en attente d'un ticket.

50
 Les services Posix de manipulation des sémaphores se trouvent dans la librairie
<semaphore.h>
 Le type sémaphore est désigné par le type sem_t.
 Initialisation d’un sémaphore:
int sem_init(sem_t *sem, int pshared, unsigned int value)
• sem est un pointeur sur le sémaphore à initialiser
• value est la valeur initiale du sémaphore
• pshared indique si le sémaphore est local au processus pshared=0 ou partagé
entre le père et le fils pshared!=0

 L’opération P : retourne toujours 0, suspend le thread appelant jusqu‘à ce que le


sémaphore pointé par sem ait une valeur non-nulle, il décrémente alors son
compteur
int sem_wait(sem_t *sem)

51

 L’opération V : retourne 0 en cas de succès ou -1 autrement. Incrémente le


compteur du sémaphore pointé par sem

int sem_post(sem_t *sem)

 L’opération permettant de récupérer la valeur d’un sémaphore : il retourne tjrs 0.

int sem_getvalue (sem_t* nom, int * sval)

 L’opération pour détruire un sémaphore. Retourne -1 s’il y a encore des waits

int sem_destroy (sem_t* nom)

• Les sémaphores servent donc à synchroniser les communications entre threads

52
 Exemple: sem_posix.c

53

 Exemple: problème des philosophes


• Pour cinq philosophes, seulement deux philosophes peuvent manger à un
instant donné car les couverts ne sont pas suffisants.

• Trois philosophes n'ont la possibilité que de penser ou d'être en attente de


vouloir manger.

• Quelque soit le nombre de philosophes, on ne peut jamais avoir deux


philosophes mangeant cote à cote, pour de "conflit de couverts".

 L'état des philosophes sera stocké dans un tableau alloué dans un segment de
mémoire partagé

 L’utilisation de ce tableau alloué en mémoire partagé, implique immédiatement


l'usage d'un sémaphore d'exclusion mutuelle.

54
 Exemple: problème des philosophes, philosophe1.c

55

 Exemple: problème des philosophes, philosophe1.c


 Cette solution résout le problème d’interblocage.

 Un philosophe peut mourir de faim car il ne pourra


jamais obtenir les fourchettes nécessaires pour manger
(problème de famine).

 Pour éviter le problème de famine il faut garantir que si


un processus demande d’entrer en section critique, il
obtient satisfaction au bout d’un temps fini.

 Lorsqu’un philosophe i ne parvient pas à prendre les


fourchettes, il se met en attente ( P(S[i]) ).

 Lorsqu’un philosophe termine de manger, il vérifie si


ses voisins sont en attente. Si c’est le cas, il réveille les
voisins qui peuvent manger en appelant l’opération V.

 On distingue trois états pour les philosophes : penser,


manger et faim.

56
 Exemple: problème des philosophes,
philosophe2.c

57

 Problème des rédacteurs et des lecteurs


• Ce problème modélise les accès à une base de données. Un ensemble de
processus tente constamment d’accéder à la base de données soit pour écrire,
soit pour lire des informations

• Pour assurer une certaine cohérence des données de la base, il faut interdire
l’accès (en lecture et en écriture) à tous les processus
o Les rédacteurs représentent les processus qui demandent des accès en
écriture à la base de données

o Les lecteurs représentent les processus qui demandent des accès en


lecture à la base de données

• Le modèle lecteur/rédacteur permet justement à plusieurs processus d’accéder


en lecture à une donnée de façon simultanée tout en garantissant l’accès
exclusif à cette donnée en écriture

58
 Problème des rédacteurs et des lecteurs
• Pour contrôler les accès à la base, on a besoin de connaître le nombre de
lecteurs (NbL) qui sont en train de lire
• Le compteur NbL est un objet partagé par tous les lecteurs.
• L’accès à ce compteur doit être exclusif (sémaphore mutex)
• Un lecteur peut accéder à la base, s’il y a déjà un lecteur qui accède à la base
(NbL>0) ou aucun rédacteur n’est en train d’utiliser la base
• Un rédacteur peut accéder à la base, si elle n’est pas utilisée par les autres (un
accès exclusif à la base)
• Pour assurer cet accès exclusif, on utilise un autre sémaphore : Redact

NbL<-0 // Nb Lecteurs
semaphore Redact // écrivain
semaphore Mutex // accès à la base

59

 Problème des rédacteurs et des lecteurs

60
 Producteur/consommateur
• Deux processus partagent une mémoire tampon de taille fixe. Les deux
processus ne doivent pas accéder en même temps au tampon

 Le producteur
• Met des informations dans la mémoire tampon, et l’autre, les retire
• Peut produire uniquement si le tampon n’est pas plein
• Doit être bloqué tant et aussi longtemps que le tampon est plein

 Le consommateur
• Peut retirer un objet du tampon uniquement si le tampon n’est pas vide
• Doit être bloqué tant et aussi longtemps que le tampon est vide

61

 Producteur/consommateur avec sémaphores utilise trois sémaphores


• Le premier sémaphore, nommé plein, compte le nombre d’emplacements
occupés. Il est initialisé à 0, utilisé par le consommateur
• Le second, nommé vide, compte le nombre d’emplacements libres. Il est
initialisé à N (la taille du tampon), utilisé par le producteur
• Le dernier, nommé mutex, assure l’exclusion mutuelle pour l’accès au
tampon (lorsqu’un processus utilise le tampon, les autres ne peuvent pas y
accéder)

 Le producteur attend si le
tampon est plein :
P(vide). Il est réveillé dès
que le tampon n’est plus
plein: V(vide)
 Le consommateur attend
si le tampon est vide :
P(plein). Il est réveillé
dès que le tampon n’est
plus vide : V(plein)

62
 Le sémaphore vide contrôle le nombre de cases vides
 Le producteur exécute P(vide) pour réserver une case
 Le consommateur exécute V(vide) pour libérer une case
 Le producteur exécute V(plein) pour signaler au consommateur 1 nouveau
message dans le tampon
 Le consommateur exécute P(plein) pour attendre un message

 Pas d’interblocage:
Le producteur et le consommateur
ne peuvent être bloqués simultanément,
respectivement sur P(vide) et P(plein)

63

Exemple: taille 1

Sans synchronisation

Avec synchronisation

64
Plan

 La notion des threads

 Communication entre threads

 Synchronisation

• Verou

• Semaphore

• Moniteur

65

 Un moniteur est une structure de variables et de procédures pouvant être


paramétrée et partagée par plusieurs process.

 On dit que l'entrée du moniteur par un processus exclut l'entrée du


moniteur par un autre processus.

 Au lieu d'être dispersées dans plusieurs processus, les sections critiques


sont transformées en procédures d'un moniteur.

 La gestion des sections critiques n'est plus à la charge de l'utilisateur, mais


elle est réalisée par le moniteur.

 Il utilise des variables de type condition et deux primitives agissant sur


elles :
o WAIT : bloque le processus appelant et autorise un processus en
attente à entrer dans le moniteur,
o SIGNAL : réveille le processus endormi en tête de la file d'attente.

66
 Les moniteurs proposent une solution de «haut-niveau» pour la protection
de données partagées.

 Ils simplifient la mise en place de sections critiques.

 Seul un processus (ou tâche ou thread) peut être actif à un moment donné
à l'intérieur du moniteur.

 La demande d'entrée dans un moniteur (ou d'exécution d'une primitive du


moniteur) sera bloquante tant qu'il y aura un processus actif à l'intérieur du
moniteur.

 L'accès à un moniteur construit donc implicitement une exclusion


mutuelle.

67

 Variables de condition: permet à une thread de se mettre en attente


d’une condition logique (prédicat) du programme, tout en libérant
l’exclusion mutuelle imposée par le mutex.

int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex);

 L’activité appelante doit posséder le verrou mutex.

 L’activité est alors bloquée sur la variable condition après avoir


libéré le verrou.

 L’activité reste bloquée jusqu’à ce que la variable condition soit


signalée et que l’activité ait réussi à réacquérir le verrou.

68
int pthread_cond_signal (pthread_cond_t *cond_wait);

 Signale la variable condition:


o Une activité bloquée sur la variable condition est réveillée.
o Cette activité tente alors de réacquérir le verrou correspondant
à son appel de cond_wait.
o Elle sera effectivement débloquée quand elle réussira à
réacquérir ce verrou.
o Il n’y a aucun ordre garanti pour le choix de l’activité réveillée.
o L’opération signal n’a aucun effet s’il n’y a aucune activité
bloquée sur la variable condition (pas de mémorisation).

int pthread_cond_broadcast (pthread_cond_t *cond);

 Toutes les activités en attente sont réveillées, et tentent d’obtenir le


verrou correspondant à leur appel de cond_wait.

69

 Exemple du parking:

70
 Exemple du parking:

71

 Samia Bouzefrane, Les Systèmes d’exploitation: Cours et Exercices corriges Unix,


Linux et Windows XP avec C et JAVA (566 pages), Dunod Editeur, Octobre 2003,
ISBN : 2 10 007 189 0.

 Jean-François Peyre, supports de cours sur l’informatique industrielle-systèmes


temps réel, CNAM(Paris).

 A. Queudet, Cours Systèmes d'exploitation, Univ. Nantes

 M. DALMAU - IUT de Bayonne - Les systèmes d'exploitation.

 http://queinnec.perso.enseeiht.fr/Ens/SC/precis.pdf

72

Vous aimerez peut-être aussi