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

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

Apr 03, 2015

Download

Documents

Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
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