43
1 Trois points importants: • Comment partager les ressources? • Concurrence pour l'utilisation des ressources • Synchronisation Communication interprocessus

1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

Embed Size (px)

Citation preview

Page 1: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

1

Trois points importants:

• Comment partager les ressources?

• Concurrence pour l'utilisation des ressources

• Synchronisation

Communication interprocessus

Page 2: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

2

1. A voit que la prochaine case disponible est 7 puis est remplacé par B

2. B voit que la prochaine case disponible est 7, y place le nom de son fichier, puis est remplacé par A

3. A place le nom de son fichier dans une case qu’il croit libre écrasant le nom donné par B

Conditions de concurrence

Deux processus veulent accéder à la mémoire partagée en même temps.

Par exemple: Les processus A et B veulent utiliser la file d’impression.

Page 3: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

3

Sections Critiques (1)

L’exclusion mutuelle est une méthode qui permet de s’assurer que si un processus utilise une variable ou un fichier partagé, les autres processus seront exclus de la même activité.

Une section critique (ou région critique) est la partie du programme à partir de laquelle on accède à la mémoire partagée.

Page 4: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

4

Sections Critiques (2)

Quatre conditions pour obtenir l'exclusion mutuelle:1. Un seul processus à la fois dans la section critique

2. Aucune supposition sur le nombre et la vitesse des CPUs

3. Aucun processus hors de la section critique ne peut bloquer un autre processus.

4. Aucun processus ne doit attendre indéfiniment pour entrer en section critique.

Page 5: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

5

Sections critiques (3)

Exclusion mutuelle à l'aide des sections critiques.

Page 6: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

6

Solutions à l’exclusion mutuelle

• Désactivation des interruption:• Instruction disable• On ne peut pas permettre aux usagers d’utiliser une telle instruction

• Variable de verrou • Un processus peut entrer seulement si VERROU=0 Il met alors VERROU=1 pour empêcher les autres processus d’entrer• Cette solution ne fonctionne pas!

Page 7: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

7

Alternance stricte

Proposition de solution au problème de la section critique(a) Processus 0. (b) Processus 1.

Page 8: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

8

Solution de Peterson (1981)#define FALSE 0#define TRUE 1#define N 2 /* nombre de processus */int turn;  /* à qui le tour ? */int interested[N];  /* toutes valeurs initialement 0 (FALSE) */

void enter_region(int i) { /* le processus est 0 ou 1 */ int other;  /* nombre des autres processus */ other = 1 - i;  /* l’opposé du processus */ interested[i] = TRUE;  /* montre que i est intéressé */ turn = i;  /* au tour de i */ while (turn == i && interested[other] == TRUE) ;

/* instruction null */ }

void leave_region(int i) { /* i: processus qui quitte */ interested[process] = FALSE;  /* indique le départ de la section critique */}

Page 9: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

9

Solution de Peterson (n processus)

// Il y a n processus. Chaque processus doit franchir n-1 niveaux // avant d'accéder à la section critique. int interested[n] // interested[i]=j si le processus i est intéressé a passer au niveau j int turn [n-1] // turn[j]=i si c'est au tour du processus i de passer au niveau j

void enter_region(int i) { // Le processus i veut entrer en section critique for j=1 to n-1 do interested[i]=j turn[j]=iL: for k=1 to i-1, i+1 to n

if ( (turn[j]==i) and (interested[k]j) ) goto L}

void leave_region(int i) { // Le processus i sort de la section critique interested[i]=0;}

Page 10: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

10

L'instruction TSL (Test and Set Lock)

TSL R, LOCK est une opération atomique équivalente à:R=LOCK

LOCK=1

enter_region: TSL REGISTER,LOCK | copie lock dans le registre et le définit à 1 CMP REGISTER,#0 | lock était-il à 0 ? JNE enter_region | s'il n’était pas à 0, boucle RET | retourne à l’appelant ; entre en section critique

leave_region: MOVE LOCK,#0 | stocke un 0 dans lock RET | retourne à l’appelant

Page 11: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

11

L'instruction XCHG (Intel x86)

XCHG R, LOCK échange le contenu de R et LOCK

Cette instruction peut facilement remplacer TSL

enter_region: MOVE REGISTER, #1 | Mettre 1 dans REGISTER XCHG REGISTER,LOCK | Échanger REGISTER et LOCK CMP REGISTER,#0 | lock était-il à 0 ? JNE enter_region | s'il n’était pas à 0, boucle RET | retourne à l’appelant ; entre en section critique

leave_region: MOVE LOCK,#0 | stocke un 0 dans lock RET | retourne à l’appelant

Page 12: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

12

Opérations Sleep et Wakeup (1)

Alternative aux solutions par attente active vues jusqu’à présent.

Ex. Problème du producteur-consommateur

#define N 100 /* nombre de connecteurs dans le tampon */int count = 0;  /* nombre d’éléments dans le tampon */void producteur(void){ int item; while (TRUE) { item = produire_item( );  /* génère l’élément suivant */ if (count == N) sleep( );  /* si le tampon est plein, entre en sommeil */ ajouter_item(item);  /* place l’élément dans le tampon */ count = count + 1;  /* incrémente le décompte des éléments dans le tampon */ if (count == 1) wakeup(consommateur);  /* le tampon était vide ? */ }}

Page 13: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

13

Opérations Sleep et Wakeup (2)

void consommateur(void){ int item; while (TRUE) { if (count == 0) sleep( );  /* si le tampon est vide, entre en sommeil */ item = enlever_item( );  /* prélève un élément dans le tampon */ count = count - 1;  /* décrémente le décompte des éléments dans le tampon */ if (count == N - 1) wakeup(producteur);  /* le tampon était plein ? */ utiliser_item(item);  /* utilise l’élément */ }}

Que se passe-t-il si le producteur fait un wakeup entre le moment ou le consommateur constate que le tampon est vide et celui où il appelle sleep?

Page 14: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

14

Les sémaphores: opérations Up et Down (1)

Solution de Dijkstra au problème des wakeup perdus.

Un sémaphore est une variable partagée entre plusieurs processus et munie de deux nouvelles instruction atomiques:

Down(S): if (S==0) sleep S=S-1 Up(S): S=S+1 if (S==1) wakeup() // si des processus sont endormis sur le // sémaphore S alors l’un d’eux sera réveillé

Page 15: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

15

Les sémaphores

#define N 100 /* nombre d’emplacements dans le tampon */typedef int semaphore;  /* les sémaphores sont un type de variable int spécial */semaphore mutex = 1;  /* contrôle l’accès à la section critique */semaphore empty = N;  /* compte les emplacements vides dans le tampon */semaphore full = 0;  /* compte les emplacements pleins */

void producer(void){ int item; while (TRUE) { item = produce_item( ); /* génère quelque chose à placer dans le tampon */ down(&empty);  /* décrémente le décompte des emplacements vides */ down(&mutex);  /* entre en section critique */ insert_item(item);  /* place un nouvel élément dans le tampon */ up(&mutex);  /* quitte la section critique */ up(&full);  /* incrémente le décompte des emplacements pleins */ }}

Résolution au problème du producteur-consommateur.On utilise trois sémaphores:

Page 16: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

16

Les sémaphores

void consumer(void){ int item; while (TRUE) { down(&full);  /* décrémente le décompte des emplacements pleins */ down(&mutex);  /* entre en section critique */ item = remove_item();  /* prélève un élément dans le tampon */ up(&mutex);  /* quitte la section critique */ up(&empty);  /* incrémente le décompte des emplacements vides */ consume_item(item);  /* fait quelque chose avec l’élément */ }}

Page 17: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

17

Sémaphores sur Windows

HANDLE WINAPI CreateSemaphore(LPSECURITY_ATTRIBUTES lpsa, LONG lInitialCount, // Nombre de ressources initialement disponiblesLONG lMaximumCount, // Nombre maximale de ressourcesLPCTSTR lpName

);

DWORD WINAPI WaitForSingleObject(HANDLE hSemaphore,DWORD dwMilliSeconds // Peut être INFINITE

);

BOOL WINAPI ReleaseSemaphore( HANDLE hSemaphore, LONG lReleaseCount, // Nombre de ressources à remettreLPLONG lpPreviousCount // Reçoit le nombre de ressource actuelle);

Page 18: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

18

Sémaphores sur Solaris#include <semaphore.h>

sem_t *sem_open(char* nom, // Le premier caractère du nom doit être '/'int oflag // O_CREAT ou O_CREAT | O_EXCLint mode // bits de permissionint valeur // valeur initiale

);

int sem_wait(sem_t *psem)

int sem_post(sem_t *psem)

int sem_init( // sémaphore sans nomsem_t * psem, int pshare, // Si non nul, peut être partagé avec d'autres processus int

valeur // NULL = Attributs par défaut);

Page 19: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

19

Sémaphores sur Solaris

#include <semaphore.h>

main() { sem_t my_semaphore; int rc; rc = sem_init(&my_semaphore, 0, 10); …}

Page 20: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

20

Les mutexLes mutex sont des sémaphore qui ne peuvent prendre que la

valeur 0 ou 1. Ils servent à réaliser l’exclusion mutuel.Voici comment utiliser l’instruction TSL pour implémenter :

mutex_lock et mutex_unlock

mutex_lock: TSL REGISTER,MUTEX | copie mutex pour enregistrer et définir mutex à 1 CMP REGISTER,#0 | mutex était-il à 0 ? JZE ok | si oui, il n’était pas verrouillé, donc retourne CALL thread_yield | mutex est occupé ; planifie un autre thread JMP mutex_lock | réessaye plus tardok: RET | retourne à l’appelant ; entrée en section critique

mutex_unlock: MOVE MUTEX,#0 | stocké un 0 dans mutex RET | retourne à l’appelant

Page 21: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

21

Mutex sur Solaris

#include <pthread.h>

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

int pthread_ mutex_lock(pthread_mutex_t* pm);

int pthread_mutex_unlock(pthread_mutex_t* pm);

int pthread_mutex_init( // mutex dynamiquepthread_mutex_t * pm, const pthread_mutexattr_t *mattr // NULL = Attributs par défaut

);

Page 22: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

22

Mutex sur Windows

HANDLE WINAPI CreateMutex (LPSECURITY_ATTRIBUTES lpma, // Pour nos applications ce paramètre

// peut être mis à NULLBOOL bInitialOwner, // True pour créer et posséder le mutexLPTSTR lpName // Nom pour partager le mutex avec d'autres processus

// ( Peut être NULL));

DWORD WINAPI WaitForSingleObject(HANDLE hMutext,DWORD dwMilliSeconds // Peut être INFINITE

);

BOOL WINAPI ReleaseMutex( HANDLE hMutex );

Page 23: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

23

Critical Section sur Windowsvoid WINAPI InitializeCriticalSection(

LPCRITICAL_SECTION lpCriticalSection );

void WINAPI EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection

);

BOOL WINAPI InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION lpCriticalSection,

DWORD dwSpinCount );

void WINAPI LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection

);

Page 24: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

24

Critical Section sur Windows// Variable globaleCRITICAL_SECTION CriticalSection;

DWORD WINAPI ThreadProc( LPVOID lpParameter ){ ...EnterCriticalSection(&CriticalSection); ... // Accès à la ressource partagée.LeaveCriticalSection(&CriticalSection); ...}

void main(){ ... InitializeCriticalSection(&CriticalSection) ... // Création des threads DeleteCriticalSection(&CriticalSection) ... }

Page 25: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

25

Variables conditionelles

Permet à un thread de se bloquer non pas à l’entrée d’une région critique mais en fonction d’une certaine condition

définie par la valeur d’une variable.

Ex. Plusieurs threads se partage une variable P qu’ils incrémentent à tour de rôle.

Un des threads veut se bloquer tant que P n’aura pas pas

atteint une certaine valeur.

Page 26: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

26

Variables conditionelles sur Windows Vista

VOID WINAPI InitializeConditionVariablePCONDITION_VARIABLE cond

);

BOOL WINAPI SleepConditionVariableCS( // De façon atomique, bloque etPCONDITION_VARIABLE cond, // relâche la section critiquePCRITICAL_SECTION pcs,DWORD millisecond

);

VOID WINAPI WakeConditionVariable( // Débloque un thread bloquéPCONDITION_VARIABLE cond // sur la variable de condition

);

VOID WINAPI WakeAllConditionVariable( // Débloque tous les threads bloqués

PCONDITION_VARIABLE cond // sur la variable de condition );

Page 27: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

27

Variables conditionelles sur Solarispthread-cond_t cond = PTHREAD_COND_INITIALIZER;

int pthread_cond_wait(pthread_cond_t *cond,pthread_mutex_t *mutex

);

int pthread-cond_signal(pthread_cond_t *cond);

int pthread_cond_broadcast(pthread_cond_t *cond);

int pthread_cond_init( pthread_cond_t *cond,const pthread_condattr_t *attr

);

Page 28: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

28

Les barrières

• Utilisation des barrières– Les processus s'approchent de la barrière– Tous les processus sauf un sont bloqués– Le dernier processus arrive, libérant les autres

Page 29: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

29

Les barrières sur Solaris

int pthread_barrier_init(pthread_barrier_t * barrier, const pthread_barrierattr_t * attr, unsigned count);

int pthread_barrier_wait(pthread_barrier_t *barrier);

int pthread_barrier_destroy(pthread_barrier_t *barrier);

Page 30: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

30

Passage de messages

Deux primitives:

1. Send(destination, &message)2. Receive(source, &message)

3. En l’absence de message disponible, le récepteur peut se bloquer jusqu’à ce que celui-ci arive.

Page 31: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

31

Le problème du producteur-consommateur avec N messages

Page 32: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

32

File d'attente de message sur Solaris#include <sys/msg.h>

int msgget( key_t key, //IPC_PRIVATE ou une valeur de clef valide int msgflg ); // bits de permissison ( &IPC_CREAT pour créer la file)

struct msgbuf{long mtype, char* mtext} msg;

int msgsnd( int msqid, const void *msgp, //pointeur sur le message size_t msgsz, // taille du message int msgflg); // 0 pour suspendre le thread si la file est pleine

int msgrcv( int msqid, void *msgp, size_t msgsz, long int mtype, // premier membre de msgbuf int msgflg); // 0 pour suspendre le thread si la file est vide

Page 33: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

33

Le dîner des philosophes (1)

• Les philosophes mangent et pensent

• Mangent avec 2 fourchettes

• Prennet une seule fourchette à la fois

• Comment prévenir les interbloquages ?

Page 34: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

34

Le dîner des philosophes (2)

Cette solution ne fonctione pas

Page 35: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

35

Le dîner des philosophes (3)

Page 36: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

36

Le dîner des philosophes (4)

Page 37: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

37

Le dîner des philosophes (5)

Page 38: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

38

Le problème des lecteurs et des rédacteurs

Permet de modéliser les accès aux bases de données.

Un processus qui écrit doit avoir un accès exclusif à la base de données

Les processus qui lisent n’ont pas besoin dd’un accès exclusif.

Page 39: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

39

Le problème des lecteurs et des rédacteurs

Page 40: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

40

Le problème des lecteurs et des rédacteurs

Page 41: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

41

Le problème du barbier endormi (1)

Page 42: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

42

Le problème du barbier endormi (2)

Page 43: 1 Trois points importants: Comment partager les ressources? Concurrence pour l'utilisation des ressources Synchronisation Communication interprocessus

43

Le problème du barbier endormi (3)