0% ont trouvé ce document utile (0 vote)
192 vues136 pages

Synchronisation et IPC avec Threads

Ce document traite de la synchronisation et de la communication entre processus. Il présente différentes solutions au problème de section critique, notamment des solutions matérielles comme le masquage d'interruptions et le TAS, et des solutions logicielles comme les verrous, les drapeaux et l'algorithme de Peterson.

Transféré par

Chafik Berdjouh
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
192 vues136 pages

Synchronisation et IPC avec Threads

Ce document traite de la synchronisation et de la communication entre processus. Il présente différentes solutions au problème de section critique, notamment des solutions matérielles comme le masquage d'interruptions et le TAS, et des solutions logicielles comme les verrous, les drapeaux et l'algorithme de Peterson.

Transféré par

Chafik Berdjouh
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Chap.

III SYNCHRONISATION ET

COMMUNICATION ENTRE PROCESSUS

(et threads)

(IPC – Inter Process Communication)

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 1


Plan des IPCs

1) Outils de synchronisation à attente active (TSL, verrous)

2) Sémaphores

3) Moniteurs

4) Problèmes classiques de synchronisation:


synchronisation RDV, P/C, L/R, philosophes, …

5) Les IPCs threads (Posix + java en complément)


complément

Mutex, sémaphores, variables conditionnelles

6) Communication –par passage de messages

a) Les pipes Unix

b) Les signaux Unix

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 2


Exemple introductif

Int i;
P1 P2
P
i=0; i=0;
while (i<10) while (i>-10)
i++; i--;
printf(‘’P1 GAGNE! \n’’); printf(‘’P2 GAGNE !\n’’);

i variable partagée risque de conflit d’accès!


Les instructions i++ et i– doivent s’exécuter de manière indivisible!
Lequel des processus P1 ou P2 gagne?
Vont-ils terminer? Si l’un se termine, est-ce que l’autre termine aussi?
Est-ce que P1 peut commencer?

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 3


Présentation du problème
Pas d’interaction:
Exécution dans n’importe quel ordre
Exécution parallèle ou concurrente
Interactions entre processus:
Nécessité de synchroniser
L’ordre d’exécution est important
Cas particulier: Exclusion mutuelle –sérialisation des exécutions
Moyens de synchronisation:
Matériel: masquage d’interruption et TAS—Test-And-Set
Logiciel: verrous, sémaphores, moniteurs, et passage par messages
Niveau d’abstraction
- +
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 4
Définitions de synchronisation, Section critique

Synchronisation
Utilisation d’opérations atomiques afin de garantir une bonne
coopération entre processus.
Une opération qui consiste à distribuer, dans le temps, les accès à
une ressource partagée entre plusieurs processus.
Conditions de rapidité
un ordre quelconque de processus/instructions peut produire des
résultats incorrects
La commutation dépend, dans le cas
de concurrence, de l’ordonnancement
de parallélisme, de la vitesse d’exécution relative– on
synchronise le processus le plus rapide sur le processus le plus
lent.
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 5
Section critique --SC
Une partie d’un programme où se produit un conflit d’accès.
Comment éviter ce conflit?
Besoin de contrôler l’entrée à une SC
Besoin de supporter l’exclusion mutuelle dans la SC.
Une bonne solution au problème de SC doit satisfaire:
1. Exclusion mutuelle (accès exclusif):
exclusif) à tout instant un seul processus
exécute sa SC (ressource partagée).
partagée)
2. Avancement et absence de blocage: un processus qui n’est pas
dans sa SC ne doit bloquer un autre processus à entrer en SC; c-à-d
pas d’attente s’il n’y a pas de compétition
3. Attente bornée (pas de famine):
famine une fois la demande d’entrée en
SC est lancée, le processus ne doit pas attendre indéfiniment. La
demande est assurée de manière équitable, si possible.
Aucune hypothèse ne doit être faite sur les vitesses relatives des
processus
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 6
Structure Typique d’un Processus

Soient N processus exécutant le programme suivant:

Do

// ’’Entrer en SC’’ } Prologue

SC

// ’’Sortir de la SC’’ } Epilogue


SNC
While (1);

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 7


Solutions Possibles

Hypothèses:
Vitesses relatives des processus quelconque et inconnu
tout processus quitte sa SC au bout d’un temps fini
Aperçu

Opérations
atomiques de haut Verrous Sémaphores Moniteurs Send/Receive
niveau (API)
- +
Opérations
atomiques de bas
niveau (matériel) Load/Store Masquage Interruption TAS

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 8


Solutions Matérielles

Permettre à l’utilisateur d’interdire momentanément les interruptions


(difficile et dangereuse!)
Augmenter l’ensemble des actions atomiques
Masquage d’interruptions
Problème: les processus users ne peuvent pas garantir le test et la
modification d’une variable
Solution: Interdire la commutation de processus pendant qu’un processus
est en SC ou encore masquer les Its (le système peut le faire en mode
SVC par un appel spécifique).
Masquer It
SC
Demasquer It
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 9
Solutions Matérielles –TAS (TSL)
TAS --Test-And-Set (ou TSL –Test and Set Lock): Instruction spéciale câblée dont le
rôle est de rendre atomique le ‘’test and set’’ du contenu d’un mot.
Int TAS (int *val)
{ int temp;
temp= *val; //implantée de manière atomique
*val = 1;
return temp;
}
Une solution au problème de SC pour n processus:
processus
Int verrou = 0; void MutexDebut()
Processus Pi {
Do while (TAS(&verrou))
MutexDebut(); ;
SC }
MutexFin(); void MutexFin()
SNC { verrou = 0; }
while (1);
Preuve?
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10
Solutions Logicielles –Attente
Attente Active sur un Verrou

Soient deux processus P0 et P1


Algorithme1: A qui le tour!
Public //Variables partagées
int tour=0; //tour =i si Pi veut entrer en SC
Processus Pi
Do
while (tour != i)
; // on fait rien
SC
tour = (i+1)%2;
SNC
While (1);
Démontrer que c’est une fausse solution?
Exclusion mutuelles satisfaite
Avancement non vérifié: si P0 est plus lent que P1 alors P0 bloque P1;
bien qu’il n’est pas dans sa SC
Nécessité d’une alternance stricte (jeton)
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 11
Algorithme2: deux drapeaux

Public //Variables partagées


int flag[2]=0[2]; //flag[i]=0 si Pi est prêt pour entrer en SC
Processus Pi
Do
flag[i] = 1;
while (flag[j])
; // on fait rien
SC
flag[i] = 0;
SNC
While (1);
Démontrer que c’est une fausse solution?
Exclusion mutuelles satisfaite
Avancement non vérifié: si les processus arrivent en même temps, c.-à-d.
flag[0] = flag[1] =1!
Une vraie solution consiste à combiner les deux dernières!

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 12


Algorithme3: Solution de Peterson (2 processus)
Public //Variables partagées
int flag[2]=[0]; //flag[i]=0 si Pi est prêt pour entrer en SC
int tour = 0;
Processus Pi
Do
flag[i] = 1;
tour = j; // j = (i+1)%2;
while (flag[j] && tour == j)
; // on fait rien
SC
flag[i] = 0;
SNC
While (1);

Preuve de correction?
Cet algorithme satisfait les 3 conditions de SC, à démontrer?
Généralisation à n processus: voire algorithme de Bakery

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 13


Attente active --Conclusion

Solutions qui fournissent des attentes actives


Inefficace: il faut que le processus en attente libère le processeur
explicitement (exemple la fonction sleep sous Unix).
Les processus de priorité élevé peuvent être prives (inversion de
priorité)
Solutions de blocage
Sémaphores
Moniteurs
Send/Receive

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 14


Les SEMAPHORES
Motivation : synchronisation des processus concurrents
Une approche par attente active n’est pas intéressante, puisque le processeur est
immobilisé simplement pour attendre
Gaspillage de la puissance CPU disponible
Une approche alternative = utilisation de sémaphores
Principe et définition des sémaphores
Mécanisme de synchronisation simple et ancien entre des processus concurrents
Le principe est directement hérité des chemins de fer -- Signal muni d’un bras
indiquant si la voie ferrée est libre ou occupée
Sémaphore levé : le processus P peut continuer son chemin
Sémaphore baissé : il doit attendre jusqu'à ce qu’un autre processus Q le lève
Eviter des collisions en assurant l'accès exclusif à un croisement ferré
Syntaxe et Sémantique
Un sémaphore S est une structure de données manipulant uniquement 3 opérations
atomiques : initialisation, P et V sur une variable entière.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs


Sémaphores: inventé par Dijkstra

Edsger Dijkstra

Né à Rotterdam le 11 mai 1930 et mort à Nuenen le 6 août 2002,


est un mathématicien et informaticien néerlandais du
XXe siècle

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 16


Syntaxe et Sémantique d’un Sémaphore
P --passer : P(S)/Wait(S)/Down(S)
Décrémenter la variable S (à moins qu’elle ne soit déjà à 0)
Utilisée (lorsque déjà 0) pour bloquer (suspendre) le processus appelant jusqu'à
ce qu’un événement survienne.
V --relâcher : V(S)/Signal(S)/Up(S)
Incrémenter le sémaphore de 1
Utilisée pour signaler un événement, et si possible, réactiver un processus en
attente.
Initialisation de S: interprétée comme un nombre d’autorisations (disponibles quand
l’entier est positif, attendues quand le nombre est négatif).
Déclaration de sémaphores -- Notation d’Andrews
Sem S1, S2; Sem ingred[3]=([3] 1); S1 = 0; S2 = 1;
Apres initialisation, les seules opérations permises sont P et V
Sémaphores général vs. sémaphore binaire :
Sémaphore général : peut prendre n ’importe quelle valeur non-négative
Sémaphore binaire : la valeur peut être uniquement 0 ou 1

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 17


Syntaxe et Sémantique d’un Sémaphore (suite)
Sémaphore associé à une file d’attente -- Sémaphore de blocage
A chaque sémaphore est associée une file d’attente pour les processus bloqués
Création d’un sémaphore général
typedef struct semaphore {
int valeur;
bcp *tete; }
void P(semaphore *S)
{ if ( --S->valeur < 0) {
insérer ce processus dans la FA associée
se Bloquer }
}
void V(semaphore *S)
{ if ( ++S->valeur <= 0) {
supprimer un processus courant de la FA associée à ce sémaphore
Réveiller un processus ( prêt)}
prêt)
}
L’utilisation correcte des sémaphores ne doit pas dépendre d’une gestion particulière de la
file d’attente
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 18
Utilisation des Sémaphores

Les sémaphores peuvent être utilisés tant pour la réalisation des sections critiques que pour
diverses formes de synchronisation conditionnelle
Compétition entre 2 processus Coopération -- sémaphore privé
Variables partagées Variables partagées
Semaphore Mutex=1; Semaphore Sync = 0;
Processus Pi Processus P0 Processus P1
Repeat ....... .......
P(Mutex); P(Sync); V(Sync);
SECTION CRITIQUE ....... .......
V(Mutex);
until flase; Il existe une relation de précédence P1 < P0
Conséquence :
Un sémaphore est toujours initialisé à une valeur non-négative mais peut devenir
négative après un certain nombre d'opérations P(S) -- nombre des processus en attente.
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 19
Problèmes de dysfonctionnement des sémaphores
Remarques :
La plupart des mises en œuvre des sémaphores assurent que les processus en attente
sont réactivés dans l’ordre dans lequel ils ont été suspendus sur le sémaphore.
Equité dans l’ordonnancement des processus
Les sémaphores sont les principales primitives de synchronisation dans Unix
Un sémaphore est un mécanisme qui permet le blocage et le réveil explicite.
Servir à traiter tous les paradigmes de la programmation concurrente
Aucune garantie qu’une synchronisation est exempte de problèmes!! :
Interblocage (Deadlock) -- attente circulaire
Un processus est bloqué indéfiniment s’il est en attente d’un événement qui ne
peut être produit que par le processus déjà en attente
Considérons 2 processus utilisant 2 sémaphores d’exclusion mutuelle
P1 P2
P(S1) P(S2)
P(S2) P(S1)
... ...
Famine (starvation) : des processus qui s'exécutent indéfiniment sans aucun
changement; certains processus peuvent ne jamais obtenir les ressources!
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 20
Attente active vs. Blocage

L ’attente active est-elle plus coûteuse que le blocage?


Coût de blocage contre le coût de manipulation des files d ’attente + la
commutation de contexte?
La durée de l ’attente?
L’attente active peut être meilleure pour des sections critiques de
courtes durées, plus particulièrement pour les multiprocesseurs, elle
est incontournable.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 21


Problèmes Classiques de Synchronisations

Problème du Rendez-vous (RDV) et/ou Barriere

Problème des Producteur(s)-Consommateur(s)


Consommateur(s)

Problème des Lecteurs- Rédacteurs

Problème du diner des philosophes (spaghettis avec 2 fourchettes)

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 22


Problèmes Classiques de Synchronisations

Rendez-vous -- Principe général


P1 P2 Pn

Point de Point de
rendez-vous synchronisation

Version simplifiée du problème pour 2 processus (généralisation -- voir TD)


Synchronisation par sémaphores privés :
Semaphores arrivee1=0, arrivee2 = 0;
Processus P1 Processus P2
...... .......
V(arrivee1); // signaler mon arrivée V(arrivee2);
P(arrivee2); // attendre l'arrivée de l’autre P(arrivee1);
...... ......
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 23
TD (en classe)

Généraliser la solution du problème de RDV pour n processus

P1 P2 Pn

Point de Point de
rendez-vous synchronisation

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 24


Problème de Producteur/Consommateur (tampon borné)

Vide
N cases
Producteur Consommateur

Plein

Contraintes de synchronisation :
Relation de précédence : Producteur < Consommateur
Section critique (tampon)
tampon plein Producteur se bloque
tampon vide Consommateur se bloque
Exclusion mutuelle au tampon

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 25


Solution au Problème de Producteur/Consommateur (tampon
borné)

Variables partagées
#define N 100
Semaphore mutex=1; /* protège l'accès au tampon */
Semaphore plein=0; /* compte le nombre d ’informations produites dans le tampon */
Semaphore vide = N; /* Nb d ’emplacements libres dans le tampon */
Processus Producteur Processus Consommateur
Repeat Repeat
...... ......
Produire_objet(); P(plein); /* décrémenter nb info. */
...... P(mutex); /* entrée en SC */
P(vide) /* dec. Cases libres */ retirer_objet();
P(mutex); /* entrée en SC */ V(mutex); /* sortie de SC */
deposer_objet(); V(vide); /* Incr. nb cases vides */
V(mutex); /* sortie de SC */ Consommer_objet()
V(plein); /* Incr. nb info. */ until false;
until false;
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 26
Problème des Lecteurs/Rédacteurs

Considérons ce problème comme étant un système de réservation de billets d’avions où


plusieurs processus tentent de lire et d'écrire des informations:
On accepte que plusieurs lisent ensemble (degré d'accès >= 1)
On n’autorise qu’un seul processus à modifier (on exclut les lecteurs et les autres
rédacteurs) Exclusion mutuelle (degré d'accès = 1)
On suppose que les lecteurs sont prioritaires par rapport aux rédacteurs
Un rédacteur bloqué doit attendre le dernier des lecteurs pour qu’il puisse entrer en
section critique
Solution
Variables partagées
Semaphore mutex1=1; /* protège le compteur des lecteurs */
Semaphore mutex2=1; /* garantir la priorité des lecteurs)
Semaphore wrt=1; /* exclusion mutuelle pour les rédacteurs */
int nblect=0; /* Nombre de lecteurs arrivés */

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 27


Solution au Problème des Lecteurs/Rédacteurs
avec priorité des lecteurs par rapport aux rédacteurs

Processus Lecteur Processus Rédacteur


......
P(mutex1); /* accès exclusif à nblect */ P(mutex2); /* priorité des lecteurs*/
if (++nblect == 1) P(wrt); /* accès exclusif */
P(wrt); /* se bloquer ou causer le blocage
les rédacteurs */ Ecriture
V(mutex1); /* libérer l ’utilisation de nblect */ V(wrt); /* libérer l'accès exclusif */
Lecture V(mutex2);

P(mutex1);
if (--nblect == 0) /* si le dernier lecteur */
V(wrt); /* autoriser une écriture */
V(mutex1);
...... -- II2
ENSI - F. Najjar SE &PC -- Les IPCs 28
TD (en classe)

Solution au Problème des Lecteurs/Rédacteurs

avec priorité des rédacteurs par rapport aux lecteurs

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 29


Les MONITEURS

Motivation :
Les sémaphores peuvent être utilisés pour résoudre à peu près n'importe quel
problèmes d'exclusion mutuelle ou synchronisation ... mais les sémaphores possèdent
certains désavantages :
Mécanisme de bas niveau qui demande une discipline sévère dans la façon dont
ils sont utilisés, sous peine d'erreurs:
d'erreurs que se passe-t-il si on oublie d'indiquer un
appel à V? ou si on effectue une action P en trop?
Le rôle d'une opération P ou V (exclusion mutuelle? synchronisation
conditionnelle?) dépend du type de sémaphore, de la façon dont il est initialisé et
manipulé par les divers processus pas explicite
Moniteur :
Mécanisme de synchronisation de haut niveau, proposé par Hoare et Brinch Hansen.
Forme de module qui supporte, à l’aide de deux mécanismes indépendants,
l ’exclusion mutuelle et la synchronisation conditionnelle.
Conceptuellement, un moniteur simule une classe en OO (des variables partagées et
les méthodes qui les manipulent)
Un moniteur est censé assurer une exclusion mutuelle (un seul processus actif
dans le moniteur) d’accès aux données qu’il contient
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 30
Syntaxe et Sémantique d’un Moniteur

Structure d’un Moniteur VARIABLES Partagées


- d’Etat
- Condition

Procédures
Externe Internes
Points s
d'entrée

Sémantique d’un Moniteur =


Type abstrait, mais avec des propriétés d’exclusion mutuelle et de synchronisation
lorsque le moniteur est partagé par plusieurs processus.
On n’a accès qu’aux procédures externes, pas aux variables
Les procédures sont exécutées en exclusion mutuelle et donc les variables internes
sont manipulées en exclusion mutuelle
On peut se bloquer et réveiller d’autres processus. Le blocage et le réveil
s’exprime au moyen de conditions.
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 3
Syntaxe et Sémantique d’un Moniteur (suite)

Syntaxe : la forme générale d’une déclaration de moniteur :


Monitor nom_moniteur {
/* --- Déclarations des variables --- */
.....; /* variables d'états */
Condition ... ; /* variables conditions */
/* ------------ Déclarations des procédures ------------ */
Public nom_fonction (...)
{ .... }
Public void nom_procedure (..)
{ .... }
Private .... (...)
{ ..... }
{ /* -- Initialisation des variables ---*/
} -- II2
ENSI - F. Najjar SE &PC -- Les IPCs 3
Exclusion Mutuelle

Philosophie des moniteurs = séparer de façon claire l ’exclusion mutuelle de la


synchronisation conditionnelle (coopération):
(coopération)
L’exclusion mutuelle est supportée de façon implicite : un appel, par un processus,
d’une procédure exportée par le moniteur assure que la procédure sera exécutée de
façon exclusive, c-à-d, au plus un appel d’une procédure du moniteur sera actif à un
instant donné le moniteur maintient une FA des processus en attente d'entrée.
Les synchronisations conditionnelles doivent être décrites de façon explicite à l ’aide de
variables condition (Condition variables)
En d’autres termes, l’exclusion mutuelle est automatique, sa mise en œuvre étant assurée
par le langage (compilateur), la librairie, ou le système d ’exploitation, pas le programmeur
lui-même.
Langages de programmation
JAVA (le meilleur) déclarations en exclusion mutuelle
(‘’synchronized’’) certaines méthodes d ’une classe.
ADA95 -- type protégé, objet protégé « protected »; ainsi, toutes les
procédures de ces objets protégés sont exécutées en exclusion
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 3
mutuelle.
Variables de Condition
Une variable condition est utilisée pour suspendre un processus jusqu'à ce qu’une certaine
condition devienne vraie.
Déclarée comme une variable, mais on ne peut ni lui attribuer de valeur ni la tester) --
Condition C;
Servir de FA des processus qui attendent sur cette condition
3 opérations possibles sur une variable condition C :
Empty(C) // La FA associée est-elle vides ?
Mise en attente d’un processus : Wait(C) // le processus appelant se bloque et
doit libérer le moniteur.
Réactivation de processus en attente : Signal(C) // reprend exactement un
processus (en tête de la FA associée à C). Si aucun processus n ’est suspendu alors
cette opération est sans effet.
Problème de signalisation : un processus P fait un signal et réveille un processus Q,
alors qui aura le contrôle exclusif du moniteur? 2 approches :
Signaler et continuer : le processus qui exécute signal continue son exécution, donc
conserve l'accès exclusif au moniteur. Le processus ayant été signalé sera exécuté plus
tard Approche non-préemptive -- la plus couramment utilisée (Unix, Java, Pthreads).
Signaler et Attendre : le processus qui signale attend pendant que celui qui vient d'être
signale acquiert l accès exclusif au moniteur
ENSI - F. Najjar -- II2 3
SE &PC -- Les IPCs
Similitudes/Différence entre P/Wait
P/ et V/Signal

Les opérations Wait et P peuvent toutes deux avoir pour effet de suspendre un
processus qui exécute cette opération :
Wait suspend toujours le processus
P ne le fait que si la valeur du sémaphore est négative ou nulle
Signal et V peuvent réactiver un processus suspendu :
Signal n ’a aucun effet si aucun processus n’est suspendu,
alors que V aura pour effet d’incrémenter la valeur du sémaphore si aucun
processus n ’est suspendu.
Implantation des moniteurs par des sémaphores :
Assurer l ’exclusion mutuelle au moniteur mutex (P entrée V après sortie)
A chaque variable condition sont associés un sémaphore et un compteur
Wait (V(mutex); P(semcond))

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs


Exemples classiques de synchronisation --
Solutions par Moniteurs

Les problèmes de RDV à n processus et des Lecteurs/Rédacteurs avec


priorité des lecteurs (en classe).

Problème de Producteur/Consommateur à tampon borné

Monitor PC_TB {

#define N 100;

private objet Tampon[N]; //tampon borné

private int count=0; //nombre d’objets déposés

private condition plein, vide;


ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 3
Moniteur de Producteur/Consommateur

public void deposer (objet x) public void retirer (objet x)


{ {
if (count == N) if (count == 0)
wait(plein); wait(vide);
deposer_objet(tampon, x); retirer_objet(tampon, x);
count++; count--;
signal(vide); signal(plein);
} }
}

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 3


Problèmes classiques avec Moniteurs

à faire en classe)

1. Problème du RDV (n)

2. Problème des L/R (avec différentes priorités)

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 3


ENSI -- II2-SE&PC FN

IPC (suite)
Synchronisation avec les threads

PLAN

Introduction

Primitives de synchronisation avec PThreads

Verrous (mutex)

Sémaphores

Variables conditionnelles
Introduction --Niveau
Niveau de Concurrence

Interprocessus
Processus i-l Processus i Processus i+1 Gros grain
(Niveau processus)

Processus func1 ( ) func2 ( ) func3 ( ) Intraprocessus


Contrôle { { { Grain moyen
.... .... .... (niveau contrôle)
Données .... .... .... Function (thread)
Matériel } } }

a ( 0 ) =.. a ( 1 )=.. a ( 2 )=.. Grain fin


b ( 0 ) =.. b ( 1 )=.. b ( 2 )=.. (niveau données)

Grain très fin


+ x Load (niveau matériel)
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 4
Exemple Simple de Thread POSIX
void *func ( )
{
/* define local data */
- - - - - - - - - - -
- - - - - - - - - - - /* code de la function */
pthread_exit(exit_value);
}

int main ( )
{
pthread_t tid;
int exit_value;
- - - - - - - - - - -
pthread_create (&tid, NULL, func, NULL);
- - - - - - - - - - -
pthread_join (tid, &exit_value
exit_value);
- - - - - - - - - - -
exit(0);
}
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 41
Introduction --Synchronisation
Synchronisation des THREADS

La plupart des programmes multithreadés ont des threads qui interagissent les uns avec les
autres.

Partage de variables globales –Accès concurrent (R?/W?)

Besoin de synchroniser: imposer un ordre d’exécution des threads ou sérialiser l’ accès à


la ressource partagée

Nécessité de Protection

Modification concurrente < x = 0x01> || < x = 0x100> x= ?

Exécution concurrente < a=x; x=a+ 1;> || < b=x; x=b -1;> x = -1/0/1?

Cohérence mémoire : < x = 1; y = 2;> || < printf(‘’%d


printf %d ’’, x, y); > affichage de 0/2?

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 4


Actions/Instruction Atomique? --Rappel

Une action/instruction qui doit commencer et finir à s’exécuter sans aucune possibilité

d’interruption

Une instruction machine a besoin d’être atomique (pas toutes!)

Une ligne de code C a besoin d’être atomique (pas toutes!)

a besoin d’être atomique (pas toutes!)

Peut-on fournir une instruction atomique complexe?

Une section de code qui est forcée à être atomique est une section Critique

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 43


Section Critique: Mauvaise Programmation!
T1
T2
reader()
{ writer()
- - - - - - - - - {
lock(DISK); - - - - - - - - - -
......... ..............
......... ..............
......... - - - - - - - - - -
unlock(DISK); }
- - - - - - - -
}

Shared Data
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 44
Section Critique: Bonne Programmation!

T1
T2
reader()
{ writer()
........... {
lock(DISK); ...........
........... lock(DISK);
........... ..............
........... ..............
unlock(DISK); unlock(DISK);
........... ...........
} }

Shared Data
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 45
Synchronisation Pthread

Plusieurs outils de synchronisation :


les verrous -- locks : (pour assurer l’exclusion mutuelle--MUTEX)
Verrous lecteur/rédacteur : permet de réaliser une synchronisation de type
lecteur/rédacteur
les sémaphores : pour résoudre l’exclusion mutuelle, pour synchroniser.
Problème : interblocage possible
les variables conditionnelles -- condition variables : pour attendre qu’un état, décrit par un
prédicat soit vrai
elles résolvent le problème de l’interblocage
interblocage.
les barrières : une barrière bloque un ensemble de threads jusqu’à ce que tous les threads
aient atteint la barrière.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 4


Synchronisation – Faux Exemple (du TP gestion des threads)

Illustration du problème de partage de mémoire par les threads : quelle sera la valeur affichée par main ?
longint val = 0; void fonc(void)
void main(void) { long int i;
{ pthread_t tid1, tid2; pthread_t tid;
void fonc(void); for (i=0; i <1000000; i++)
pthread_set_concurrency(2); val = val + 1;
pthread_create(&tid1, NULL, (void *(*)()) fonc,, NULL); tid = pthread_self();
pthread_create(&tid2, NULL, (void *(*)()) fonc,, NULL); printf("tid : %d valeur = %d\n", tid, val);
pthread_join(tid1, NULL); }
pthread_join(tid2, NULL);
printf("valeur = %ld\n", val);
}
Remarque : join est nécessaire. Sans join le processus n’attend pas la fin des threads, il se termine et
entraîne la fin de tous les threads créés.

4
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs
Synchronisation – Faux Exemple (suite)
Voici les résultats de quelques exécutions différentes, pourquoi ces différences ?
tid : 4 val = 1342484
tid : 5 valeur = 1495077
val = 1495077
tid : 4 val = 1279685
tid : 5 val = 1596260
val = 1596260
tid : 5 val = 1958900
tid : 4 val = 2000000
val = 2000000
L’incrémentation de valeur se fait en plusieurs instructions machine!:
Ranger valeur dans un registre
Incrémenter le registre
Ranger le registre dans valeur
Si la fin de quantum intervient après la phase 1, le contexte mémorise l'état du registre à cet instant. Lors de la
restauration du contexte, le registre reprend cette valeur, les incréments effectués entre-temps par l'autre thread
seront donc écrasés...
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 4
Synchronisation -- Verrou d’Exclusion Mutuelle

Demande
de la ressource

File d’attente

Libération
Section critique de la ressource
Compétition pour une
ressource
(Donnée, code non
réentrant)

Le temps passé dans une section critique doit être court


4
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs
Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A

Thread D

Free
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 50


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A

Lock Thread D

Free
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 51


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A

Lock Thread D

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 52


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A

Lock Thread D

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 53


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A

Thread D

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 54


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock

Thread D

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 55


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock

Thread D

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 56


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock Lock

Thread D

Lock

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 57


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock Lock

Thread D

Lock

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 58


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock Lock
Unlock
Thread D

Lock

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 59


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock Lock
Unlock
Thread D

Lock

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 60


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock Lock

Thread D

Lock

Free
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 61


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock Lock

Thread D

Lock

Free
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 62


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock Lock

Thread D

Lock

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 63


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock Lock

Thread D

Lock

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 64


Acquisition et Libération de Verrous (Locks)
(

Thread B Thread C

Thread A
Lock

Thread D

Lock

Set
Lock

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 65


Les Verrous d’exclusion Mutuelle --Mutex
Déclaration et initialisation
Création statique: pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
Création dynamique:
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, & attributs);
attributs)
Pour les attributs, NULL correspond aux valeurs par défaut
les attributs permettent le partage du mutex entre plusieurs processus (via la mémoire
partagée).
Utilisation d’un verrou :
Demande de verrou :
Demande suspensive : pthread_mutex_lock(&mutex);
pthread_mutex_lock
Tentative sans blocage: pthread_mutex_trylock(&mutex);
pthread_mutex_trylock renvoie 0/EBUSY/EINVAL-EFAULT
Libération du verrou par le thread qui la pris (verrouillé)
pthread_mutex_unlock(&mutex); la libération des threads se fait de façon aléatoire.
Destruction d’un verrou :
pthread_mutex_destroy(&mutex); détruit le mutex qui doit être déverrouillé

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs


Les Mutex

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs


Les Verrous d’Exclusion Mutuelle -- Exemples
Reprenons l’exemple précédent. Pour en assurer le bon fonctionnement, il faudrait modifier la boucle ainsi :
Avant modification : for (i=0; i <1000000; i++) val = val + 1;
Après modification :
for (i=0; i <1000000; i++) {
pthread_mutex_lock (&verrou);
val = val + 1;
pthread_mutex_unlock (&verrou);
}
Exemple 2 : Deux threads T1,et T2 doivent assurer une contrainte de cohérence sur les données x et y , qui est ici : x = y.
thread_mutex_t verrou;
int x, y;
Thread T1 Thread T2
••• •••
pthread_mutex_lock(&verrou); pthread_mutex_lock (&verrou);
x = x + 1; x = 2 * x;
y = y + 1; y = 2 * y;
pthread_mutex_unlock(&verrou); pthread_mutex_unlock(&verrou)
••• •••

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 6


Les Verrous -- Interblocage
mutex M1, M2;
Thread A : Thread B :
Lock(M1); //1. A verrouille M1 Lock(M
(M2); // 2. B verrouille M2
Lock(M2); // 3. A se bloque sur M2 Lock(M
(M1); / 4. B se bloque sur M1
Solution:
Concevoir sans deadlock -- imposer un ordre (acyclique) sur les verrous, qui doivent nécessairement être
demandés en respectant cet ordre.
Inversion de priorité :
Soient trois threads A, B, et C, tels que A est de forte priorité, B de priorité moyenne, et C de faible priorité ainsi
qu’un verrou m.
A et B sont bloqués
C s'exécute et verrouille m
B se réveille et préempte B
A tente de verrouiller m et se bloque
B reprend la main
Tant que B ne se bloque pas, C ne peut pas s'exécuter et libérer le verrou nécessaire à la poursuite de A.
Solution (rarement implantée) : modifier la priorité de C pour le rendre aussi prioritaire que A jusqu'à ce qu’il ait
libéré le verrou
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs
Avoiding Deadlocks
Establish a hierarchy : Always lock Mutex_1
Mutex_ before Mutex_2, etc..,.
Use the trylock primitives if you must violate the hierarchy.
{ while (1)
{ pthread_mutex_lock (&m2);
if(EBUSY != pthread mutex_trylock (&m1))
break;
else
{ pthread _mutex_unlock (&m1);
wait_around_or_do_something_else
wait_around_or_do_something_else();
}
}
do_real work(); /* Got `em both! */ }
Use lockllint or some similar static analysis program to scan your code for hierarchy
violations.
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 70
Synchronisation -- Les Sémaphores

les sémaphores peuvent être utilisés par des threads appartenant à différents processus; inclure l’interface
(#include<semaphore.h>) et le type est sem_t.
la libération des threads bloqués se fait de façon aléatoire (!).

Nom de la fonction Rôle de la fonction


sem_init (sem_t *S, shared p, unsigned int valeur) Initialisation du sémaphore

sem_destroy (sem_t *S) Suppression du sémaphore


sem_wait (sem_t *S) Attend que la valeur du sémaphore soit
positive puis la décrémente
positive,
sem_trywait (sem_t *S) Décrémente le compteur s'il est positif,
sinon erreur
sem_post (sem_t *S) Incrémente le compteur et libère
éventuellement un thread.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 7


Synchronisation -- les Variables Conditionnelles
les variables conditionnelles s'utilisent conjointement à un verrou afin d’éviter des interblocages.
Déclaration et initialisation
Création statique: pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
PTHREAD_COND_INITIALIZER
Création dynamique: pthread_cond_init(&cond cond, &attributs);
Pour les attributs, NULL = valeur par défaut
Les attributs permettent le partage des variables de condition entre plusieurs processus (lourds - via la mémoire
partagée).
Utilisation
Attente de la condition : pthread_cond_wait(&cond cond, &mutex);
L’attente est toujours associée à un mutex
Le verrou mutex est libéré au moment de la mise en attente (blocage)
Signalisation de la condition: pthread_cond_signal(&cond), ou encore
pthread_cond_broadcast(&cond);
Une (tous) thread(s) en attente sur la condition sont réveillés
Ils sont alors à nouveau en compétition pour le mutex (pour le réacquérir).
Destruction d’une variable condition : pthread_cond_destroy(&cond);
pthread_cond_destroy
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs
Synchronisation -- les Variables Conditionnelles (suite)

7
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs
Les Variables Conditionnelles -- Exemple (Producteur/Consommateur)
#include <pthread.h>
#include <string.h>
#include ’’prodcons.h’’
static char *buffer; /*Tampon partagee de taille =1*/
static pthread_cond_t libre, plein; static pthread_mutex_t protect;
void init_prodco (void) /* ----- Initialise le producteur/consommateur ----------*/
{ pthread_mutex²_init(&protect, NULL); pthread_cond_init(&libre,
pthread_cond_init NULL);
pthread_cond_init(&plein, NULL); buffer = NULL; }
void *deposer(char *msg) char *retirer(void)
{ pthread_mutex_lock(&protect); { char *result;
while ( buffer != NULL) pthread_mutex_lock(&protect);
pthread_cond_wait(&libre, &protect); while (buffer == NULL)
buffer = strdup(msg); pthread_cond_wait(&plein, &protect);
pthread_cond_signal(&plein); result = buffer; buffer = NULL;
pthread_mutex_unlock(&protect); pthread_cond_signal(&libre);
return NULL; pthread_mutex_unlock(&protect);
} return result; }
7
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs
Les barrières avec Mutex et Variables conditionnelles

A barrier holds a thread until all threads participating in the barrier have reached it.

Barriers can be implemented using a counter, a mutex and a condition variable.

A single integer is used to keep track of the number of threads that have reached the

barrier.

If the count is less than the total number of threads, the threads execute a condition wait.

The last thread entering the barrier (and setting the count to be the same as the number of

threads) wakes up all the threads using a condition broadcast.

7
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs
Les barrières Pthread API

typedef struct {

pthread_mutex_t count_lock;

pthread_cond_t ok_to_proceed;

int count;

} barrier_t;

void barrier_init(barrier_t *b) {

pthread_mutex_init(&(b->count_lock), NULL);
NULL)

pthread_cond_init(&(b->ok_to_proceed), NULL);

b->count = 0; }
7
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs
Les barrières Pthread API
void barrier (barrier_t *b, int num_threads)
num_threads
{
pthread_mutex_lock(&(b->count_lock)) ));
b->count++;
if (b->count == num_threads) {
b->count = 0;
pthread_cond_broadcast(&(b->ok_to_proceed
ok_to_proceed));
}
else {
while (b->count != 0)
ok_to_proceed), &(b->count_lock));
pthread_cond_wait(&(b->ok_to_proceed
}
pthread_mutex_unlock(&(b->count_lock
count_lock));
}
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs
Synchronisation - Récapitulatif (1)

Verrou d’exclusion mutuelle ( mutex-lock)


l'outil le plus rapide et le moins consommateur de mémoire.
mémoire Il doit être rendu par le thread qui l'a pris . Il
s'utilise surtout pour sérialiser l'accès à une ressource ou assurer la cohérence des données.

Sémaphore
consomme plus de mémoire et s'utilise dans les cas où on se synchronise sur l'état d'une variable, plutôt qu'en attendant
une commande venue (cond_signal) d'un autre thread. Il n'exige pas que le verrouillage/déverrouillage soit fait par le
même thread.
Variables conditionnelles (condition variables)
Une variable conditionnelle s'utilise pour attendre l'occurrence d'un événement.
Le verrou qu’on doit lui associer sert à gérer l’exclusion mutuelle sur les variables internes liées à cette variable
conditionnelle (compteur).
Ce verrou est automatiquement rendu par le système lors de l’appel à cond_wait et repris dès la sortie de cette
fonction. Il doit être rendu par l’utilisateur après cette sortie.
sortie

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs


Synchronisation - Récapitulatif (2)

Visibilité:
les outils de synchronisation peuvent être vus par des threads appartenant à des processus DIFFERENTS :

Passage à l’état bloqué, sortie de cet état :


L’appel à cond_wait est toujours bloquant (à la différence de lock ou sem_wait)
cond_signal ne fait qu’essayer de débloquer un thread, le signal est perdu si aucun thread n'est bloqué lors de
son émission (alors que V incrémente un compteur)
pour éviter les interblocages, utiliser les verrous ou les sémaphores suivant un ordre fixe, ou utiliser les
variables conditionnelles

Performances :
Attention à l’inversion de priorité

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs


Conclusions sur IPC threads: threads ou non threads?

Profiter pleinement des multicores

Améliorer le ’’Throughput’’ Implémenter des E/S Asynchrones

Bien profiter des propriétés du noyau système

Si toutes les opérations sont CPU Bound ne pas aller plus loin dans le
multithreading

La création d’un thread n’est pas coûteuse, mais elle n’est pas gratuite

1 thread qui a seulement 4-5


5 lignes de code devrait être très utile!

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 80


Annexe: The APIs

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 81


Different Thread Specifications
Functionality UI Threads POSIX Thteads NT Threads OS/2 Threads

Design Philosophy Base Near-Base Complex Complex


Primitives Primitives Primitives Primitives
Scheduling Classes Local/ Global Local/Global Global Global
Mutexes Simple Simple Complex Complex
Semaphores Simple Simple Buildable Buildable
R/W Locks Simple Buildable Buildable Buildable
Condition Variables Simple Simple Buildable Buildable
Multiple-Object Buildable Buildable Complex Complex
Synchronization
Thread Suspension Yes Impossible Yes Yes
Cancellation Buildable Yes Yes Yes
Thread-Specific Data Yes Yes Yes Yes
Signal-Handling
Primitives Yes Yes n/a n/a
Compiler Changes
Required No No Yes No
Vendor Lib. MT-safe? Most Most All? All?

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 82


POSIX and Solaris API Differences

POSIX API Solaris API

continue
join suspend
thread cancellation
exit key creation
scheduling policies semaphore vars
priorities sigmask create
sync attributes thread specific data concurrency setting

thread attributes mutex vars kill reader/ writer vars


condition vars daemon threads

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 83


COMMUNICATION INTERPROCESSUS

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 84


Plan de la communication interprocessus

1. Définitions et Propriétés de communication

2. Pipes Unix

3. Les signaux

4. Les files de messages (MSQ)

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 85


Moyens de communication

Moyens de communication interprocessus intra-machine (UNIX)

Appartenant au système de gestion de fichiers

Pipes anonymes

Pipes nommés

Famille des IPC (Inter Processus Communication)

Files de messages (MSQ)

Les signaux

Moyens de communication interprocessus inter-machines

sockets, RPC, RMI, …

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 86


Communication par Messages

Deux opérations fondamentales :

Emettre : send(destination, message)

Recevoir : receive(source, message)

Les messages sont de tailles variables ou fixes

L'envoi et la réception peuvent être soit directes entre les processus à


travers l'identifiant du destinataire,
destinataire soit indirectes par l'intermédiaire
d'une boite aux lettres.

Il existe des variantes de send/receive en fonction des sémantiques :

send(destination, message) : bloquante ou non?

receive(source, message) : synchrone ou non?

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 87


Styles de Communication par Messages

Unidirectionnel : les messages suivent un seul sens (les pipes d'Unix ou


Producteur/Consommateur).

Processus P Processus Q
(producteur) Send (consommateur)

Receive

Bidirectionnel : les messages suivent un cercle (Client/Serveur, Appel de


procédure à distance -- RPC)

Processus P Processus Q
(producteur) Réponse (consommateur)

Demande

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 88


Propriétés Fondamentales de la Communication
-- Identification 1 --
Comment sont spécifiées destination et source?
Chaque processus écrit le nom du destinataire à qui le message est
envoyé ou bien le nom de la source à partir de laquelle le message est
reçu Processus P Processus Q

message = .... ;
Send(Q, message); Receive(P, message);

Support de
communication

Nom processus = processus@machine{.domaine}


processus@machine
Multicast/Broadcast : envoi à tous/un
tous groupe de destinataires
Jockers (Wildcard) : en PVM send(-1, msge); receive(-1, -1)
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 89
Propriétés Fondamentales de la Communication
-- Identification 2 --
Communication par boite aux lettres (file de messages)

Processus P Processus Q
BAL

Send(BAL,msge)
Receive(BAL,msge
)

Principe de la boite aux lettres :


BAL pleine l'émetteur se bloque jusqu'à ce qu'il y aurait de la place
BAL vide le récepteur se bloque jusqu'à ce qu'un message soit placé
Prévoir une BAL par classe de processus
éviter la réception d'un message à partir d'un processus destinataire
qcq.
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 90
Propriétés Fondamentales de la Communication
-- Mode de communication

Envoi asynchrone: en général send non bloquante:

Le processus émetteur continue son exécution même si le récepteur


n'a pas retiré son message.

Envoi de plusieurs messages : ordre de retrait = ordre d'émission

Réception synchrone: receive bloquante

Attente jusqu'à ce qu'un processus source envoit un message

Rendez-Vous : send et receive sont bloquantes :

Le premier qui arrive attend l'autre;


l'autre quand l'émetteur et le récepteur
correspondant sont en attente, le message est transféré et les deux
sont permis de continuer.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 91


Propriétés Fondamentales de la Communication
-- Tampons/Taille des messages --

Manipulation des tampons:

Les messages sont copiés directement de la mémoire de l'émetteur?

Est-ce qu'ils sont copiés d'abord dans un certain tampon système entre
les deux processus?

Taille des messages :

Taille limite de message à transférer?


transférer court? long? de taille fixe?

Conclusion sur les propriétés de la communication :

Toutes les propriétés ne sont pas indépendantes:

Par exemple la primitive send non bloquante n'est généralement


accesssible qu'à travers la manipulation des tampons.
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 92
Problème du Producteur/Consommateur
Consommateur (Tampon borné)
-- Synchronisation par messages --

Processus Producteur Processus Consommateur


{
{
int x, i;
message msg;
int x;
message msg;
for (i=0; i<N; i++)
send(producteur, &msg);
While true {
While true {
produire_objet(& x);
receive(producteur, &msg);
receive(consommateur, &msg);
extraire_objet(&msg, &x);
packet_msge(&msg, x);
consommer_objet(x);
send(consommateur, &msg);
send(producteur, &msg);
}
}
}
}

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 93


Communication par PIPES (Unix-Linux)
(Unix

Unix est un système basé sur le passage de messages :


Un shell Unix: le signe "|"

API: appel système "pipe”

Un pipe permet à 2 processus de s'exécuter en même temps; le 1er


fournissant les données que le snd exploite au fur et à mesure de leur
production.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 94


Les PIPES: Definition et types

Un pipe est un canal unidirectionnel en mode flots d'octets


Fichier spécial à usage interne pour la communication
Un processus, producteur, fournit (écrit) des données dans le pipe,
l’autre processus, consommateur,
consommateur l'exploite (lit).
L'information disparait (implicement
implicement/explicitement) après lecture.
Deux types de pipes (SGF):
Les pipes anonymes: entre processus avec lien de parenté.
Les pipes nommés (FIFO): entre processus sans lien de parenté.
Unix offre 2 primitives d'émission et de réception :
Write(int desc, char *buf, int taille): non bloquante
Read(int desc, char *buf, int taille):
taille bloquante
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 95
Les PIPES anonymes--
anonymes Exemple
#include<errno.h>
#include<stdio.h>
#include<unistd.h> /*contient l'appel système pipe */
void main (void) {
int tube[2] /* deux descripteurs de pipe : 0 --> lecture et 1 --> écriture */
char car1; /* caractère de l'alphabet*/
int ret; /*Valeur de retour du fils*/

pipe(tube); /* Création du tube -- tampon interne */


switch (fork()) /*Création d'un processus fils*/
fils
case -1 : { perror("impossible de créer un processus); exit(2); }
case 0 : { close(tube[1]); /* le fils ne peut écrire dans le tube*/
while (read(tube[0], &car1,1)
car1,1)>0) /* le fils lit le tube*/
printf("%c\n", car1);
close(tube[0]) ; /* fermer le tube en lecture*/ exit (0);}
default : {close(tube[0]) /* Le père ne lit pas */
for (car1='a'; car1<='z'; car1++)
write(tube[1]), &car1, 1);; /* Le père écrit des lettres dans le tube */
close(tube[1]); /*fermer le tube en écriture */
wait(&ret); /* Blocage en attente de la fin du fils */
exit(0); } }
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 96
Pipes Unix Nommés --FIFO

Caractéristiques communes aux tubes anonymes:

communication entre processus s’exécutant sur une même

machine

fichier particulier

file de messages en mémoire

pointeurs gérés automatiquement

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 97


Pipes Unix Nommés: caractéristiques

Différences avec les tubes anonymes:


anonymes

fichier portant un nom

filiation non nécessaire

création par la fonction SGF mknod()/mkfifo()

ouverture par open()

un seul descripteur par ouverture de tube

fichier persistant

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 98


Pipes Unix Nommés
Utilisation d’un pipe nommé (FIFO
FIFO)
Créer le pipe nommé
Ouvrir le pipe en lecture et en écriture
Lire et écrire dedans
Fermer les descripteurs
supprimer le pipe (rm fichier sur le shell).
Pour pouvoir lire ou écrire dedans, il faut que le tube nommé
soit ouvert à la fois en lecture et en écriture.
Si ce n’est pas le cas les opérations de lecture/écriture sont
bloquantes.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 99


Ouverture d’un fichier

desc= open(nom_du_fichier, mode)

ouverture en lecture si mode = O_RDONLY

ouverture en écriture si mode = O_WRONLY

ouverture en maj si mode = O_RDWR

ouverture bloquante / non bloquante mode =O_NDELAY

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10


mkfifo
mkfifo()
#include <sys/types.h>

#include <sys/stat.h>

int mkfifo ( const char *fileName, mode_t mode);


int mknod (nom_du_fichier
nom_du_fichier, accès+S_IFIFO)
L’appel système mkfifo permet de créer un tube nommé (ou fifo). Cela a pour effet de
créer un fifo dans le système de fichiers.

Une fois créé le fifo peut être ouvert en lecture ou en écriture.

Les lectures ou écritures seront bloquantes tant que l’ouverture en lecture et en


écriture n’aura pas eu lieu.

Valeur renvoyée: retourne 0 en cas de succès ou la valeur -1 en cas d’erreur..

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10


Exemple de tube nommé
/* Processus ecrivain */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
main()
{ mode_t mode;
int tub;

mode = S_IRUST | S_IWUSR;


mkfifo (“fictub”,mode) /* création fichier FIFO */
tub = open(“fictub”,O_WRONLY) /* ouverture fichier */
write (tub,”0123456789”,10); /* écriture dans fichier */
close (tub);
exit(0);}
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10
Exemple (suite)
/* Processus lecteur */
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
main()
{int tub;
char buf[11];
tub = open(“fictub”,O_RDONLY) /* ouverture fichier */
read (tub,buf,10); /* lecture du fichier */
buf[11]=0;
printf(“J’ai lu %s\n,
n, buf);
close (tub);
exit(0); }

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10


Exercice pipe anonyme

Enoncé: Ecrire un programme, qui lit des caractères sur l'entrée

standard et envoie dans un pipe les lettres et chiffres à son

processus fils. Le processus fils compte les lettres et les

chiffres et affiche les résultats à la fin.

N. B. Le processus père attend la terminaison du fils pour

s'arrêter.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10


Correction Exercice pipe anonyme
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
int main (void) {
pid_t retour ;
int tube[2], lettre = 0, chiffre = 0 ;
char k ;
pipe (tube) ;
switch (retour = fork ()) {
case -1 : perror ("Creation impossible") ;
exit(1) ;
case 0 : printf ("processus fils\n") ;
/* le tube est ici ferme en ecriture: le dernier descripteur ouvert */
/* en ecriture sur le tube sera dans le processus pere. Quand celui */
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10
Correction Exercice pipe anonyme (suite)
/* ci fermera ce descripteur, le read effectué par le fils renverra 0 */
close (tube[1]) ;
while (read (tube[0], &k, 1) 1 >0)
if (isdigit (k)) chiffre++ ; else lettre++ ;
printf ("%d chiffres recus\n", chiffre) ;
printf ("%d lettres recues\n", lettre) ;
exit (0) ;
default : printf ("pere: a cree processus %d\\n", retour) ;
close (tube[0]) ;
while (read (0, &k, 1) >0)
if (isalnum(k)) write (tube[1], &k, 1) ;
/* le tube est ici ferme en ecriture : un read sur le */
/* tube vide retournera 0 dans le processus fils */
close (tube[1]) ;
wait (0) ;
printf ("pere: a recu terminaison fils\n") ; } }
ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10
Les signaux

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs


Définition

Qu’est-ce qu’un signal?

interruption d’un processus

Fonctions utiles

envoi du signal

attente du signal

traitement à effectuer

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10


Définition (suite)

Signal = interruption logicielle

événement asynchrone

destiné à un processus

émis par un autre processus ou par le système

Les interruptions logicielles ou signaux sont utilisées pour communiquer avec un

processus.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 10


Gestion des Signaux

Réaction à un événement sans être obligé d’en tester en permanence l’arrivée.

Un signal est délivré à un processus lorsque celui-ci le prend en compte au cours de sa

propre exécution.

Les processus peuvent indiquer au système ce qui doit se passer à la réception d’un

signal.

Les signaux ne servent pas à échanger des données

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 110


Gestion des Signaux (suite)

Il est possible :

1. d’ignorer le signal;

2. de le prendre en compte par l’exécution d’une fonction particulière — qualifiée de

handler — créée pour l’occasion ;

3. de laisser le système appliquer le comportement par défaut (qui —en général —

consiste à tuer le processus).

Certains signaux ne peuvent être ni ignorés,


ignorés ni capturés.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 110


Mécanisme de traitant de signaux

Réaction à la réception d’un signal

Traitant de signal (handler)

Installation du traitant

Fonction appelée de manière asynchrone à la réception d’un signal

Reprise de l’exécution à son point d’interruption

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 110


Communication bas niveau

Transporte peu d’information: numéro de signal

Utilisée pour informer d’un événement

Accord entre émetteur et récepteur sur la sémantique de l’événement

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 111


Liste des signaux Linux

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 114


Liste des signaux Linux (suite)

Les effets de la réception de ces

signaux sur un processus sont :

Term: le processus se termine ;

Core: Term + copie de la mémoire

dans un fichier core ;

Stop: suspend l’exécution du

processus.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 114


Utilisation des signaux

Un processus peut détourner les signaux reçus et modifier son

comportement par l’appel de la fonction:


fonction

void *signal(int signal, void (*fonction)(int))

Le dernier argument est un pointeur sur une fonction qui

implémente le nouveau comportement.


comportement

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 111


Les signaux –Exemple 1

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 115


Les signaux –Exemple1
Exemple1- Exécution

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 116


Les signaux –Exemple 2

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 117


Les signaux –Exemple
Exemple 2 -Exécution

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 118


Les signaux –En
En complément

Lectures complémentaires sur les signaux Unix/Linux

1. S. Moreaud, Communication par signaux. Cours de programmation

système. IUT Bordeaux1 (France) .

2. Philippe MARQUET, Programmation des systèmes, Gestion des

signaux, Lifl(France), 2005.


2005

3. …etc

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 119


Outils de manipulation shell des outils IPC
Vous pouvez examiner l’état de toutes les structures de communications interprocessus
décrites dans cette partie — à l’exception des tubes — et connues par le système grâce à la
commande ipcs de votre shell.

% ipcs
------ Shared Memory Segments --------
key shmid owner perms bytes nattch status
------ Semaphore Arrays ------
key semid owner perms nsems
------ Message Queues --------
key msqid owner perms used-bytes messages
Pour supprimer une structure de communication interprocessus (sémaphore,
mémoire partagée, etc.) vous pouvez utiliser la commande shell
% ipcrm

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 119


Questions ...?

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 123


ANNEXE

PROBLÈME DU DINER DES


PHILOSOPHES

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 124


Le diner des philosophes (1/4)
(

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 125


Le diner des philosophes (2/4)
(

Description/Hypothèses :

– Init. On suppose cinq philosophes (possible d’avoir plus) se trouvent autour


d'une table ronde;

– chacun des philosophes a devant lui un plat de spaghetti ;

– à gauche de chaque plat de spaghetti se trouve une fourchette.

– Un philosophe n'a que trois états possibles :

• penser pendant un temps indéterminé ;

• être affamé (pendant un temps déterminé et fini sinon il y a famine) ;

• manger pendant un temps déterminé et fini.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 126


Le diner des philosophes (3/4)
(

• Des contraintes extérieures s'imposent à cette situation :


– quand un philosophe a faim, il va se mettre dans l'état «affamé» et attendre que les
fourchettes soient libres ;
– pour manger, un philosophe a besoin de deux fourchettes : celle qui se trouve à gauche de sa
propre assiette, et celle qui se trouve à droite (c-à-d les deux fourchettes qui entourent sa
propre assiette);
– si un philosophe n'arrive pas à s'emparer d'une fourchette, il reste affamé pendant un temps
déterminé, en attendant de renouveler sa tentative.
tentative

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 127


La famine

La famine est un problème que peut avoir un algorithme d'exclusion

mutuelle.

Il se produit lorsqu'un algorithme n'est pas équitable, c'est-à-dire qu'il ne

garantit pas à tous les threads souhaitant accéder à une section critique une

probabilité non nulle d'y parvenir en un temps fini.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 128


Le diner des philosophes (4/4)

Le problème consiste à trouver un ordonnancement des

philosophes tels qu'ils puissent tous manger, chacun à leur tour.

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 129


Une fausse solution au problème

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 130


Le diner des philosophes –Critique de la solution (1/3)

La procédure take_fork() attend que la fourchette spécifiée


soit disponible et s’en saisit

Cette solution ne fonctionne pas

Supposons que les cinq philosophes prennent leurs fourchette


gauche en même temps

Aucun ne pourra prendre sa fourchette droite

Il y aura un inter blocage

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 13


Le diner des philosophes –Critique
Critique de la solution (2/3)

Il est possible de modifier le programme de la façon suivante

Après qu’un philosophe a pris sa fourchette gauche, le code détermine


si sa fourchette droite est disponible

Si ce n’est pas le cas, le philosophe dépose sa fourchette gauche, attend


pendant un certain temps, puis recommence le processus

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 132


Le diner des philosophes –Critique de la solution (3/3)

• Cette proposition échoue également


– Tous les philosophes peuvent reprendre l’algorithme simultanément
– Chacun prend sa fourchette gauche, puis, constate que sa fourchette droite n’est pas
disponible, la repose et attend et ainsi de suite
– Une telle situation, au cours de laquelle tous les programmes continuent de s’ exécuter
indéfiniment mais ne progressent jamais, se nomme privation de ressource (ou famine)

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 133


Solution au diner des philosophes

• On utilise un tableau, appelé state , pour suivre l’état du philosophe: il mange, il


pense, ou il a faim et tente de s’emparer des fourchettes

• Un philosophe ne peut passer à l’état manger que si aucun de ses voisins ne mange
à ce moment la.

• On utilise un tableau de sémaphore, un par individu, de façon que les philosophe


soient bloqués si les fourchettes sont prises

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 134


Solution au diner des philosophes

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 135


Solution au diner des philosophes

ENSI - F. Najjar -- II2 SE &PC -- Les IPCs 136

Vous aimerez peut-être aussi