Titre g - PowerPoint PPT Presentation

About This Presentation
Title:

Titre g

Description:

Titre g n ral ... Synchronisation – PowerPoint PPT presentation

Number of Views:50
Avg rating:3.0/5.0
Slides: 66
Provided by: jcm52
Category:
Tags: loup | titre

less

Transcript and Presenter's Notes

Title: Titre g


1
Synchronisation
2
Objectif du chapitre
  • Création dune application ayant plusieurs
    threads
  • Synchronisations entre threads
  • Section critique
  • Mutex
  • Événement
  • Sémaphore
  • Exemples pratiques

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 sexécutent simultanément.
  • Dans les exemples suivants, nous travaillerons
    sur plusieurs solutions au problème.

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 limpression de messages
  • Début de thread
  • Texte
  • Fin de thread
  • La demande dimpression dun texte fait que le
    thread perd la main

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

6
NOSYNC main (2)
  • printf("debut du main NOSYNC\n")
  • H1CreateThread(0, 0, THREAD_A, 0, 0, 0)
  • H2CreateThread(0, 0, THREAD_B, 0, 0, 0)
  • Sleep(5000)
  • CloseHandle(H1)
  • CloseHandle(H2)
  • printf("fin du main NOSYNC\n")
  • getchar()
  • return 0

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

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

9
Résultat de lexécution
10
Synchronisation
  • Les messages sont mélangés
  • Il faut  synchroniser  lexécution des threads,
    cest-à-dire, dans notre exemple, attendre quun
    message soit terminé avant dimprimer lautre
  • Synchronisation possible par
  • Section critique
  • Mutex
  • Événement (Event)
  • Sémaphore

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é

12
Section critique fonctions (1)
  • Initialisation dune section critique
  • void InitializeCriticalSection( LPCRITICAL_SE
    CTION lpCriticalSection )
  • Entrée en section critique
  • void EnterCriticalSection( LPCRITICAL_SECTION
    lpCriticalSection )
  • Sortie dune section critique
  • void LeaveCriticalSection( LPCRITICAL_SECTION
    lpCriticalSection )

13
Section critique fonctions (2)
  • Restitution des ressources
  • void DeleteCriticalSection( LPCRITICAL_SECTION
    lpCriticalSection )
  • Variante dentrée non bloquante
  • BOOL TryEnterCriticalSection( LPCRITICAL_SECTION
    lpCriticalSection )

14
Section critique application
  • Créer une application CRITIC qui imprime
    correctement les deux messages
  • Déclaration dans main ou en variable globale
    dune variable section critique
  • Utilisation de cette variable dans thread_A et
    thread_B pour contrôler limpression des messages

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

16
CRITIC main (2)
  • InitializeCriticalSection(cs)
  • printf("debut du main CRITIC\n")
  • H1CreateThread( 0, 0, THREAD_A, cs, 0, 0)
  • H2CreateThread( 0, 0, THREAD_B, cs, 0, 0)
  • Sleep(5000)
  • CloseHandle(H1)
  • CloseHandle(H2)
  • DeleteCriticalSection(cs)
  • printf("fin du main CRITIC\n")
  • getchar()
  • return 0

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

18
CRITIC thread_B
  • DWORD WINAPI THREAD_B(LPVOID pCriticSec)
  • printf("debut du thread B\n")
  • EnterCriticalSection((LPCRITICAL_SECTION)p Criti
    cSec)
  • printf("THREAD_B la cerise ")
  • printf("sur le gateau\n")
  • LeaveCriticalSection((LPCRITICAL_SECTION)p Criti
    cSec)
  • printf("fin du thread B\n")
  • return 0

19
Résultat de lexécution
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é

21
Mutex fonctions (1)
  • Création dun Mutex
  • HANDLE 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.

22
MUTEX fonctions (2)
  • Attente de disponibilité du mutex
  • DWORD WaitForSingleObject( HANDLE
    hHandle, DWORD dwMilliseconds)
  • hHandle handle du mutex
  • dwMilliseconds INFINITE (pas de time-out)
  • valeur de retour état du mutex
  • Libération du mutex
  • BOOL ReleaseMutex(HANDLE hMutex )valeur de
    retour réussite ou non

23
MUTEX fonctions (2)
  • Attente de disponibilité du mutex
  • DWORD WaitForSingleObject( HANDLE
    hHandle, DWORD dwMilliseconds)
  • hHandle handle du mutex
  • dwMilliseconds INFINITE (pas de time-out)
  • valeur de retour état du mutex
  • Libération du mutex
  • BOOL ReleaseMutex(HANDLE hMutex )valeur de
    retour réussite ou non

24
Application MUTEX
  • Créer une application MUTEX
  • Utiliser les mutexes pour que les textes ne
    soient plus mélangés lors de limpression

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")
  • hMutexCreateMutex(NULL,FALSE,NULL)

26
MUTEX main (2)
  • H1CreateThread(0,0,THREAD_A,hMutex,0,0)
  • H2CreateThread(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

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

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

29
Résultat de lexécution
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

31
Événements fonctions (1)
  • Création dun événementHANDLE CreateEvent( LPSEC
    URITY_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

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

33
Événements fonctions (3)
  • Attente dévénementDWORD WaitForSingleObject( HA
    NDLE hHandle, DWORD dwMilliseconds)
  • Activation de lévénement
  • BOOL SetEvent(HANDLE hEvent)
  • Désactivation de lévénement
  • BOOL ResetEvent(HANDLE hEvent)

34
Événements fonctions (4)
  • Dépôt dune 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

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 sactiver mutuellement

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")

37
EVENT main (2)
  • hEventACreateEvent(NULL,TRUE,TRUE,NULL)
  • hEventBCreateEvent(NULL,TRUE,FALSE,NULL)
  • H1CreateThread(0,0,THREAD_A,0,0,0)
  • H2CreateThread(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

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

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

40
Résultat de lexécution
41
Application EVENT_NOM
  • Lapplication est du même style que EVENT, mais
    montre lusage dautres fonctionnalités
  • Événements nommés
  • Passage de donnée
  • Utilisation dun dépassement de délai
  • Le thread imprime un message ou un autre suivant
    la donnée fournie, 1 ou 2

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)

43
EVENT_NOM main (2)
  • HANDLE H1,H2
  • HANDLE hEventA,hEventB
  • LPTSTR pNomEventAL"NOM_EVENT_A"
  • LPTSTR pNomEventBL"NOM_EVENT_B"
  • printf("debut du main EVENT_NOM\n")
  • hEventACreateEvent(NULL,TRUE,TRUE,pNomEventA)
  • SetEventData(hEventA,1)
  • hEventBCreateEvent(NULL,TRUE,FALSE,pNomEventB
    )
  • H1CreateThread(0,0,THREAD_A,0,0,0)
  • H2CreateThread(0,0,THREAD_B,0,0,0)

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

45
EVENT_NOM THREAD_A (1)
  • DWORD WINAPI THREAD_A(LPVOID p)
  • DWORD dwData_A
  • DWORD dwTime_out1000
  • HANDLE hEvent_A,hEvent_B
  • LPTSTR pNomEventAL"NOM_EVENT_A"
  • LPTSTR pNomEventBL"NOM_EVENT_B"
  • printf("debut du thread A\n")
  • hEvent_AOpenEvent(EVENT_ALL_ACCESS,FALSE,pNomEve
    ntA)
  • hEvent_BOpenEvent(EVENT_ALL_ACCESS,FALSE,pNo
    mEventB)

46
EVENT_NOM THREAD_A (2)
  • while(WAIT_OBJECT_0WaitForSingleObject(hEvent_A
    ,dwTime_out))
  • dwData_AGetEventData(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

47
EVENT_NOM THREAD_A (3)
  • ResetEvent(hEvent_A)
  • SetEvent(hEvent_B)
  • printf("fin thread A\n")
  • return 0

48
EVENT_NOM THREAD_B (1)
  • DWORD WINAPI THREAD_B(LPVOID p)
  • HANDLE hEvent_A,hEvent_B
  • LPTSTR pNomEventAL"NOM_EVENT_A"
  • LPTSTR pNomEventBL"NOM_EVENT_B"
  • printf("debut thread B\n")
  • hEvent_AOpenEvent(EVENT_ALL_ACCESS,FALSE,pNomEve
    ntA)
  • SetEventData(hEvent_A,2)
  • hEvent_BOpenEvent(EVENT_ALL_ACCESS,FALSE,pNomEve
    ntB)
  • WaitForSingleObject(hEvent_B,INFINITE)

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

50
Résultat de lexécution
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 dun jeton à
    valeur maximum de 1

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 quun un jeton est pris, le compteur
    de jeton est décrémenté
  • Chaque fois quun jeton est restitué, le compteur
    de jeton est incrémenté
  • Lorsque le nombre de jetons disponibles est 0, la
    ressource nest plus disponible

53
Sémaphores fonctions (1)
  • Création dun sémaphore sans nom ou nommé
  • CreateSemaphore
  • Prise de jeton
  • WaitForSingleObject
  • Restitution de jeton
  • ReleaseSemaphore
  • Fermeture CloseHandle déjà rencontrée
  • Ouverture dun sémaphore nommé la fonction
    nest pas implémentée mais CreateSemaphore peut
    la remplacer

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

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

56
Application SEMA
  • Créer une application SEMA
  • Ressource contrôlée impression dun message
  • Utiliser un sémaphore à valeur maximum de 2 pour
    simuler une ressource quon ne peut attribuer que
    deux fois

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")

58
SEMA main (2)
  • hSemCreateSemaphore(NULL,2,2,NULL)
  • H1CreateThread(0,0,THREAD_A,0,0,0)
  • H2CreateThread(0,0,THREAD_B,0,0,0)
  • Sleep(5000)
  • CloseHandle(H1)
  • CloseHandle(H2)
  • CloseHandle(hSem)
  • printf("fin du main SEMA\n")
  • getchar()
  • return 0

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

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

61
Résultat de lexécution avec délai
62
Résultat de lexécution sans délai
63
Résultat de lexécution perturbée
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 quun
    événement unique avec WaitForSingleObject.

65
Conclusion
  • Les différentes méthodes de synchronisation ont
    été appliquées sur des exemples concrets
Write a Comment
User Comments (0)
About PowerShow.com