jc/md/lp-01/06synchronisation1. jc/md/lp-01/06synchronisation2 objectif du chapitre création dune...

65
jc/md/lp-01/06 Synchronisation 1 Synchronisation

Upload: maximilien-soulier

Post on 03-Apr-2015

104 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 1

Synchronisation

Page 2: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 2

Objectif du chapitre

• Création d’une application ayant plusieurs threads

• Synchronisations entre threads– Section critique– Mutex– Événement– Sémaphore

• Exemples pratiques

Page 3: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 3

Synchronisation

• Nous avons vu comment créer un thread dans un processus dans le chapitre précédent. Nous poursuivons maintenant avec plusieurs threads dans un même processus.

• Dans un premier exemple, “NOSYNC”, nous allons faire apparaître une difficulté lorsque plusieurs threads s’exécutent simultanément.

• Dans les exemples suivants, nous travaillerons sur plusieurs solutions au problème.

Page 4: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 4

Création de 2 Threads

• Créer un projet NOSYNC• Un process va créer 2 threads fils A et B• Ces threads font juste l’impression de messages

– Début de thread– Texte– Fin de thread

• La demande d’impression d’un texte fait que le thread perd la main

Page 5: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 5

NOSYNC main (1)

#include "stdafx.h"DWORD WINAPI THREAD_A(LPVOID p);DWORD WINAPI THREAD_B(LPVOID p); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){

HANDLE H1,H2;

Page 6: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 6

NOSYNC main (2)

printf("debut du main NOSYNC\n");H1=CreateThread(0, 0, THREAD_A, 0, 0, 0);H2=CreateThread(0, 0, THREAD_B, 0, 0, 0);Sleep(5000);CloseHandle(H1);CloseHandle(H2);

printf("fin du main NOSYNC\n");getchar();return 0;

}

Page 7: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 7

NOSYNC Thread_A

DWORD WINAPI THREAD_A(LPVOID p){ printf("debut du thread A\n"); printf("le loup et ");

printf("\nl'agneau ");printf("fin du thread A\n");

return 0;}

Page 8: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 8

NOSYNC Thread_B

DWORD WINAPI THREAD_B(LPVOID p){ printf("debut du thread B\n"); printf("la cerise"); printf("sur le gateau\n");

printf("fin du thread B\n"); return 0;}

Page 9: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 9

Résultat de l’exécution

Page 10: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 10

Synchronisation

• Les messages sont mélangés• Il faut « synchroniser » l’exécution des threads, c’est-à-

dire, dans notre exemple, attendre qu’un message soit terminé avant d’imprimer l’autre

• Synchronisation possible par– Section critique– Mutex– Événement (Event)– Sémaphore

Page 11: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 11

Section critique : types

• Les types « section critique » et « pointeur sur section critique » sont définis par des typedef

CRITICAL_SECTION cs;

LPCRITICAL_SECTION lpcs;

• Cela permet des contrôles par le compilateur et contribue à éviter un usage inapproprié

Page 12: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 12

Section critique : fonctions (1)

• Initialisation d’une section critique void InitializeCriticalSection(

LPCRITICAL_SECTION lpCriticalSection );

• Entrée en section critiquevoid EnterCriticalSection(

LPCRITICAL_SECTION lpCriticalSection );

• Sortie d’une section critiquevoid LeaveCriticalSection(

LPCRITICAL_SECTION lpCriticalSection );

Page 13: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 13

Section critique : fonctions (2)

• Restitution des ressources

void DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection );

• Variante d’entrée non bloquanteBOOL TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection );

Page 14: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 14

Section critique : application

• Créer une application CRITIC qui imprime correctement les deux messages

• Déclaration dans main ou en variable globale d’une variable section critique

• Utilisation de cette variable dans thread_A et thread_B pour contrôler l’impression des messages

Page 15: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 15

CRITIC main (1)

#include "stdafx.h"

DWORD WINAPI THREAD_A(LPVOID p);DWORD WINAPI THREAD_B(LPVOID p);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){

CRITICAL_SECTION cs;HANDLE H1,H2;

Page 16: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 16

CRITIC main (2)

InitializeCriticalSection(&cs);printf("debut du main CRITIC\n");H1=CreateThread( 0, 0, THREAD_A, &cs, 0, 0);H2=CreateThread( 0, 0, THREAD_B, &cs, 0, 0);Sleep(5000);CloseHandle(H1);CloseHandle(H2);DeleteCriticalSection(&cs);printf("fin du main CRITIC\n");getchar();return 0;

}

Page 17: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 17

CRITIC thread_A

DWORD WINAPI THREAD_A(LPVOID pCriticSec){

printf("debut du thread A\n");EnterCriticalSection(

(LPCRITICAL_SECTION)pCriticSec);printf("THREAD_A: le loup et ");printf("l'agneau\n");LeaveCriticalSection(

(LPCRITICAL_SECTION)pCriticSec); printf("fin du thread A\n"); return 0;}

Page 18: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 18

CRITIC thread_B

DWORD WINAPI THREAD_B(LPVOID pCriticSec){

printf("debut du thread B\n");EnterCriticalSection((LPCRITICAL_SECTION)p

CriticSec);printf("THREAD_B: la cerise ");

printf("sur le gateau\n");LeaveCriticalSection((LPCRITICAL_SECTION)p

CriticSec); printf("fin du thread B\n"); return 0;}

Page 19: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 19

Résultat de l’exécution

Page 20: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 20

Mutex

• Mutex : raccourci pour mutual exclusion• Objet système destiné à gérer les

synchronisations par exclusion mutuelle• Synchronisation

– Intra-processus– Inter-processus

• Alloué au plus à un thread à un instant donné

Page 21: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 21

Mutex : fonctions (1)

• Création d’un MutexHANDLE CreateMutex(

LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName );

lpMutexAttributes : NULL pour CE

bInitialOwner : prise ou non du mutex

lpName : pointeur sur un nom ou NULL

valeur retournée : création ou non du mutex, etc.

Page 22: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 22

MUTEX : fonctions (2)

• Attente de disponibilité du mutexDWORD WaitForSingleObject(

HANDLE hHandle,DWORD dwMilliseconds);

hHandle : handle du mutexdwMilliseconds : INFINITE (pas de time-out)valeur de retour : état du mutex

• Libération du mutexBOOL ReleaseMutex(HANDLE hMutex );valeur de retour : réussite ou non

Page 23: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 23

MUTEX : fonctions (2)

• Attente de disponibilité du mutexDWORD WaitForSingleObject(

HANDLE hHandle,

DWORD dwMilliseconds); hHandle : handle du mutexdwMilliseconds : INFINITE (pas de time-out)valeur de retour : état du mutex

• Libération du mutexBOOL ReleaseMutex(HANDLE hMutex );valeur de retour : réussite ou non

Page 24: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 24

Application MUTEX

• Créer une application MUTEX• Utiliser les mutexes pour que les textes ne

soient plus mélangés lors de l’impression

Page 25: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 25

MUTEX main (1)

#include "stdafx.h"DWORD WINAPI THREAD_A(HANDLE hMutex);DWORD WINAPI THREAD_B(HANDLE hMutex);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){

HANDLE hMutex,H1,H2; printf("debut du main MUTEX\n");

hMutex=CreateMutex(NULL,FALSE,NULL);

Page 26: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 26

MUTEX main (2)

H1=CreateThread(0,0,THREAD_A,hMutex,0,0);

H2=CreateThread(0,0,THREAD_B,(LPVOID)hMutex,0,0);

Sleep(5000);

CloseHandle(H1);

CloseHandle(H2);

CloseHandle(hMutex);

printf("fin du main MUTEX\n");

getchar();

return 0;

}

Page 27: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 27

MUTEX thread_A

DWORD WINAPI THREAD_A(HANDLE hMut)

{

printf("debut du thread A\n");

WaitForSingleObject(hMut,INFINITE);

printf("THREAD_A: le loup et ");

printf("l'agneau\n");

ReleaseMutex(hMut);

printf("fin du thread A\n");

return 0;

}

Page 28: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 28

MUTEX Thread_B

DWORD WINAPI THREAD_B(HANDLE hMut)

{

printf("debut du thread B\n");

WaitForSingleObject(hMut,INFINITE);

printf("THREAD_B: la cerise ");

printf("sur le gateau\n");

ReleaseMutex(hMut);

printf("fin du thread B\n");

return 0;

}

Page 29: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 29

Résultat de l’exécution

Page 30: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 30

Synchronisation par événement

• Autre forme de synchronisation plus souple que par les mutex

• Gestion plus riche des événements– Création– Prise de possession– Restitution– Transmission de données– Ouvertures multiples

Page 31: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 31

Événements : fonctions (1)

• Création d’un événementHANDLE CreateEvent(

LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState,LPTSTR lpName );

lpEventAttributes: NULL pour CE

bManualReset: TRUE autorise ResetEvent

bInitialState: TRUE événement disponible

lpName: NULL pour un événement sans nom

Page 32: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 32

Événements : fonctions (2)

• Ouverture d’événementHANDLE OpenEvent(

DWORD dwDesiredAcess,BOOL bInheritHandle,LPCTSTR lpName);

• Fournit un handle sur un événement déjà créé par CreateEvent

• Correspondance par le nom lpName

Page 33: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 33

Événements : fonctions (3)

• Attente d’événementDWORD WaitForSingleObject(

HANDLE hHandle,DWORD dwMilliseconds);

• Activation de l’événement BOOL SetEvent(HANDLE hEvent);

• Désactivation de l’événementBOOL ResetEvent(HANDLE hEvent);

Page 34: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 34

Événements : fonctions (4)

• Dépôt d’une donnéeBOOL SetEventData(HANDLE hEvent,

DWORD dwData);hEvent : handle de l’événementdwData : donnée à affecter

• Récupération de la donnée déposée

DWORD GetEventData(HANDLE hEvent);

valeur de retour : la donnée déposée

Page 35: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 35

Application EVENT

• Créer une application EVENT• EventA est créé actif dans le thread A pour

autoriser la tâche A à démarrer• EventB est créé inactif dans le thread B• La tâche A désactivera EventA en début de

tâche et activera EventB en fin de tâche• La tâche B désactivera EventB en début de

tâche et réactivera EventA en fin de tâche• Les 2 tâches vont s’activer mutuellement

Page 36: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 36

EVENT main (1)

#include "stdafx.h"DWORD WINAPI THREAD_A(LPVOID p);DWORD WINAPI THREAD_B(LPVOID p);HANDLE hEventA,hEventB; //variables globales pour…int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){

HANDLE H1,H2;printf("debut du main EVENT\n");

Page 37: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 37

EVENT main (2)

hEventA=CreateEvent(NULL,TRUE,TRUE,NULL); hEventB=CreateEvent(NULL,TRUE,FALSE,NULL);

H1=CreateThread(0,0,THREAD_A,0,0,0);H2=CreateThread(0,0,THREAD_B,0,0,0);Sleep(5000);CloseHandle(H1);CloseHandle(H2);CloseHandle(hEventA);CloseHandle(hEventB);

printf("fin du main EVENT\n");getchar();return 0;

}

Page 38: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 38

EVENT THREAD_A

DWORD WINAPI THREAD_A(LPVOID p){

printf("debut du thread A\n");WaitForSingleObject(hEventA,INFINITE);

printf("THREAD_A: le loup et ");printf("l'agneau\n");ResetEvent(hEventA);SetEvent(hEventB);printf("fin thread A\n");return 0;

}

Page 39: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 39

EVENT THREAD_B

DWORD WINAPI THREAD_B(LPVOID p){

printf("debut thread B\n");WaitForSingleObject(hEventB,INFINITE);printf("THREAD_B: la cerise ");printf("sur le gateau\n");ResetEvent(hEventB);SetEvent(hEventA);printf("fin thread B\n");return 0;

}

Page 40: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 40

Résultat de l’exécution

Page 41: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 41

Application EVENT_NOM

• L’application est du même style que EVENT, mais montre l’usage d’autres fonctionnalités :

– Événements nommés– Passage de donnée– Utilisation d’un dépassement de délai

• Le thread imprime un message ou un autre suivant la donnée fournie, 1 ou 2

Page 42: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 42

EVENT_NOM : main (1)

// EVENT_NOM.cpp : Defines the entry point for the…

#include "stdafx.h"

#include "Pkfuncs.h"//pour les fonctions SetEventData…

DWORD WINAPI THREAD_A(LPVOID p);

DWORD WINAPI THREAD_B(LPVOID p);

int WINAPI WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPTSTR lpCmdLine,

int nCmdShow)

Page 43: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 43

EVENT_NOM : main (2)

{HANDLE H1,H2; HANDLE hEventA,hEventB;LPTSTR pNomEventA={L"NOM_EVENT_A"};LPTSTR pNomEventB={L"NOM_EVENT_B"};

printf("debut du main EVENT_NOM\n");hEventA=CreateEvent(NULL,TRUE,TRUE,pNomEventA);SetEventData(hEventA,1);

hEventB=CreateEvent(NULL,TRUE,FALSE,pNomEventB);H1=CreateThread(0,0,THREAD_A,0,0,0);H2=CreateThread(0,0,THREAD_B,0,0,0);

Page 44: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 44

EVENT_NOM : main (3)

Sleep(5000);

CloseHandle(H1);

CloseHandle(H2);

CloseHandle(hEventA);

CloseHandle(hEventB);

printf("fin du main EVENT_NOM\n");

getchar();

return 0;

}

Page 45: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 45

EVENT_NOM : THREAD_A (1)

DWORD WINAPI THREAD_A(LPVOID p){

DWORD dwData_A;DWORD dwTime_out=1000;HANDLE hEvent_A,hEvent_B;LPTSTR pNomEventA={L"NOM_EVENT_A"};LPTSTR pNomEventB={L"NOM_EVENT_B"};printf("debut du thread A\n");hEvent_A=OpenEvent(EVENT_ALL_ACCESS,FALSE,pNomEventA);

hEvent_B=OpenEvent(EVENT_ALL_ACCESS,FALSE,pNomEventB);

Page 46: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 46

EVENT_NOM : THREAD_A (2)

while(WAIT_OBJECT_0==WaitForSingleObject(hEvent_A,dwTime_out)){

dwData_A=GetEventData(hEvent_A);printf("THREAD_A: fable %d : ",dwData_A);switch (dwData_A){ case 1 : printf("le loup "); printf("et l'agneau\n");

break; case 2 : printf("le lion et ");

printf("le rat\n"); break;

default : break; }

Page 47: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 47

EVENT_NOM : THREAD_A (3)

ResetEvent(hEvent_A);

SetEvent(hEvent_B);

}

printf("fin thread A\n");

return 0;

Page 48: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 48

EVENT_NOM : THREAD_B (1)

DWORD WINAPI THREAD_B(LPVOID p){

HANDLE hEvent_A,hEvent_B;LPTSTR pNomEventA={L"NOM_EVENT_A"};LPTSTR pNomEventB={L"NOM_EVENT_B"};printf("debut thread B\n");

hEvent_A=OpenEvent(EVENT_ALL_ACCESS,FALSE,pNomEventA);SetEventData(hEvent_A,2);

hEvent_B=OpenEvent(EVENT_ALL_ACCESS,FALSE,pNomEventB);WaitForSingleObject(hEvent_B,INFINITE);

Page 49: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 49

EVENT_NOM : THREAD_B (2)

printf("THREAD_B: la cerise ");

printf("sur le gateau\n");

ResetEvent(hEvent_B);

SetEvent(hEvent_A);

Sleep(2000); //suivant valeur : fin de A avant B ou de B

avant A

printf("fin thread B\n");

return 0;

}

Page 50: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 50

Résultat de l’exécution

Page 51: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 51

Sémaphore (1)

• Contrôle le nombre des accès à une ressource par la distribution de jetons

• Valeur maximale fixée à la création• Chaque utilisateur prend et restitue un ou

plusieurs jetons sur le sémaphore• Fonctionne entre processus indépendants• Exclusion mutuelle dans le seul cas d’un jeton à

valeur maximum de 1

Page 52: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 52

Sémaphore (2)

• Le nombre de jetons disponibles est égal à tout instant au nombre des utilisateurs de la ressource gérée par le sémaphore

• Chaque fois qu’un un jeton est pris, le compteur de jeton est décrémenté

• Chaque fois qu’un jeton est restitué, le compteur de jeton est incrémenté

• Lorsque le nombre de jetons disponibles est 0, la ressource n’est plus disponible

Page 53: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 53

Sémaphores : fonctions (1)

• Création d’un sémaphore sans nom ou nomméCreateSemaphore

• Prise de jetonWaitForSingleObject

• Restitution de jetonReleaseSemaphore

• Fermeture : CloseHandle déjà rencontrée • Ouverture d’un sémaphore nommé : la fonction

n’est pas implémentée mais CreateSemaphore peut la remplacer

Page 54: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 54

Sémaphores : fonctions (2)

HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,LONG lInitialCount,

LONG lMaximumCount,

LPCTSTR lpName );

• Arguments– pSemaphoreAttributes: inutilisé, NULL pour Windows CE– lInitialCount: jetons mis en jeu à la création– lMaximumCount: valeur maximale du compteur de jetons– lpName: NULL pour un sémaphore sans nom ou pointeur sur un nom pour un

sémaphore nommé

• Valeur de retour : NULL si échec ou handle

Page 55: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 55

Sémaphores : fonctions (3)

• WaitForSingleObject : déjà rencontrée• BOOL ReleaseSemaphore(

HANDLE hSemaphore,LONG lReleaseCount,LPLONG);

– ArgumentshSemaphore: handle fourni à la créationlReleaseCount: nombre des jetons à restituerlpPreviousCount: pointeur sur une variable qui sera garnie par le compteur de jeton avant la mise à jour

– Valeur de retour : réussite ou non

Page 56: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 56

Application SEMA

• Créer une application SEMA• Ressource contrôlée : impression d’un message• Utiliser un sémaphore à valeur maximum de 2

pour simuler une ressource qu’on ne peut attribuer que deux fois

Page 57: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 57

SEMA main (1)

#include "stdafx.h"DWORD WINAPI THREAD_A(LPVOID p);DWORD WINAPI THREAD_B(LPVOID p); HANDLE hSem;

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow){

HANDLE H1,H2;printf("debut du main SEMA\n");

Page 58: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 58

SEMA main (2)

hSem=CreateSemaphore(NULL,2,2,NULL); H1=CreateThread(0,0,THREAD_A,0,0,0);

H2=CreateThread(0,0,THREAD_B,0,0,0); Sleep(5000);

CloseHandle(H1);CloseHandle(H2);

CloseHandle(hSem); printf("fin du main SEMA\n"); getchar();

return 0;}

Page 59: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 59

SEMA THREAD_A

DWORD WINAPI THREAD_A(LPVOID p){

printf("debut du thread A\n"); WaitForSingleObject(hSem,INFINITE); printf("THREAD_A: le loup et l'agneau\n"); WaitForSingleObject(hSem,INFINITE); printf("THREAD_A: le lion et le rat\n"); ReleaseSemaphore(hSem,2,NULL); printf("fin du thread A\n"); return 0;

}

Page 60: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 60

SEMA THREAD_B

DWORD WINAPI THREAD_B(LPVOID p){

printf("debut du thread B\n"); Sleep(1000); //essayer en commentant la ligne WaitForSingleObject(hSem,INFINITE); printf("THREAD_B: la cerise sur le gateau\n"); ReleaseSemaphore(hSem,1,NULL); printf("fin du thread B\n"); return 0;

}

Page 61: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 61

Résultat de l’exécution avec délai

Page 62: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 62

Résultat de l’exécution sans délai

Page 63: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 63

Résultat de l’exécution perturbée

Page 64: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 64

Événements multiples

Windows CE offre la possibilité de gérer plusieurs événements par la fonction WaitForMultipleObjects.Les principes sont similaires mais on utilise des événements enregistrés grâce à un tableau.Le premier élément activé rencontré joue le même rôle qu’un événement unique avec WaitForSingleObject.

Page 65: Jc/md/lp-01/06Synchronisation1. jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations

jc/md/lp-01/06 Synchronisation 65

Conclusion

• Les différentes méthodes de synchronisation ont été appliquées sur des exemples concrets