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

Slides:



Advertisements
Présentations similaires
Module Systèmes d’exploitation
Advertisements

Génération de plate-forme
Rappels C.
Formation C débutant. Notion de compilation source.c executable Phase de compilation Fichier de texte brut, inexploitable directement par la machine Fichier.
Responsables : Joël Falcou et Jean-Thierry Lapresté
Module Systèmes dexploitation Chapitre 6 Communication Interprocessus Partie III École Normale Supérieure Tétouan Département Informatique
Conception et programmation Programmation Parallèle
Chapitre 3 Coopération et synchronisation par variables partagées
Plan du cours 5:Threads introduction Définition Création des Threads
Liste générique dans Linux 2.6 Source : Understanding the Linux kernel Chap3 processes p.87.
Système formel Nous avons introduit : signes de variables (x, y, z, …), de constantes (0, 1), d’opérations (+, ), de relations (=, ) Axiomes : ce sont.
CURSUS DE FORMATION AUX NOUVELLES TECHNOLOGIES DE DEVELOPPEMENT UV Threads Module Java Expert.
Exercice 1 1 (père) et 1 (fils) 1 (père) et 0 (fils)
Revision.
Jc/md/lp-01/06Threads1. jc/md/lp-01/06Threads2 Objectif du chapitre Génération dune application avec thread –Création dun thread –Identification dun thread.
jc/md/lp-01/05IT CE4.2 : cours1 Traitement des interruptions Cours.
Jc/md/lp-01/06Applications1 Émulateur. jc/md/lp-01/06Applications2 Objectif du chapitre Génération dapplications –WCE Console Application –WCE Application.
Jc/md/lp-01/05gestion mémoire : corrigé1 Gestion mémoire Corrigé
Jc/md/lp-01/05Communication inter processus corrigé1 Communication inter process Corrigé
Jc/md/lp-01/06Kernel Tracker1 Debugging Kernel Tracker.
Jc/md/lp-01/05TTY_IT : corrigé1 TTY_IT Corrigé. jc/md/lp-01/05TTY_IT : corrigé2 Objectif du chapitre Proposer une solution pour les exercices suggérés.
Jc/md/lp-01/05Driver élémentaire : corrigé1 Driver élémentaire Émulateur Corrigé
Jc/md/lp-01/05Trains_presentation1 Threads et Synchronisation Application train Présentation.
Jc/md/lp-01/05Driver élémentaire : présentation1 Driver élémentaire Émulateur Présentation.
Jc/md/lp-01/05Trains_corrigé1 Threads et Synchronisation Application train Corrigé
FLSI602 Génie Informatique et Réseaux
High Frequency Trading Introduction. Séminaires de 30 minutes, une fois par semaine (8 en tout) Sujets abordés – Définition dun algorithme et introduction.
Points importants de la semaine Les pointeurs. Les chaînes de caractères.
Comprendre la construction d’un arbre phylogénétique
F233 Conduite et Gestion de Projet TP PERT et GANTT
Chapitre IV Object, interfaces, classes imbriquées.
CSI3525: Concepts des Langages de Programmation Notes # 11: Sous-Programmes ( Lire Chapitre 8 )
2ième Classe (Mercredi, 13 Octobre) C++ Intro CSI2572.
Regrouper des éléments de même type et pouvoir y accéder à laide dun identificateur et dun indice. Objectif des tableaux.
Faculté I&C, Claude Petitpierre, André Maurer 1 Systèmes multi-processus C. Petitpierre
CYCLE 3 : Alternatives Faire des choix dans un programme en C 1- AIGUILLAGE SIMPLE sur CONDITION : if-else 2-AIGUILLAGE MULTIPLE sur CONDITIONS if-else.
Cours VHDL Chap 3: sémantique VHDL
© 2007 P. Van Roy. All rights reserved. 1 FSAB1402: Informatique 2 La Concurrence Déclarative Peter Van Roy Département dIngénierie Informatique, UCL
Synchronisation et communication entre processus
Processus et threads.
Approche mémoire partagée Threads – Paradigme de lapproche – Objets exécutés par les processeurs threads vs processus, – un thread possède : Ses registres,
TRAITEMENT DE STRUCTURES
Historique de SystemC Regroupe 4 courants didées: SCENIC Project : Synopsys+UC Irvine Philips System-Level Data Types, VSIA SLD DWG IMEC, Hardware-Software.
Les pointeurs Modes d’adressage de variables. Définition d’un pointeur. Opérateurs de base. Opérations élémentaires. Pointeurs et tableaux. Pointeurs et.
Les Fonctions. Définir une fonction Sections de code indépendantes que lon peut appeler à nimporte quel moment et dans nimporte quel ordre. Bout de code.
Programmation concurrente
Miguel Garzon CrUise Lab - SITE. Introduction Data Types and Sizes Constants Logic Operators Type conversions Example.
Faculté I&C, Claude Petitpierre, André Maurer Le parallélisme Introduction.
Multi-Thread Jian-Yun Nie
Communication interprocessus
Cours 11 Threads. Chapitre X threads threadPOO-L3 H. Fauconnier3 Threads threads: plusieurs activités qui coexistent et partagent des données exemples:
Introduction au Langage C
Synchronisation Classique
Procédures et fonctions
La notion de type revisitée en POO
Gestion de processus Corrigé TD 1 EFREI I
NOTIONS DE BASE DES SYSTÈMES TEMPS-RÉEL Sujets Concepts de processus/thread concurrents –Windows NT et la programmation temps réel Lectures: Chapitres.
Argc et argv Utilisation des paramètres de la ligne de commande.
Interactions entre Processus
1 Structures des données. 2  Le tableau permettait de désigner sous un seul nom un ensemble de valeurs de même type, chacune d'entre elles étant repérée.
Tutorat en bio-informatique
Programmation Système et Réseau
Les types composés Les enregistrements.
TABLEAUX des POINTEURS TRAITEMENT DE STRUCTURES
Pthread Ordonnancement. #define _MULTI_THREADED #include #ifndef _CHECK_H #define _CHECK_H /* headers used by a majority of the example program */ #include.
Conception de Programmes - IUT de Paris - 1ère année Conception de Programmes Objectifs et organisation du cours Introduction à la P.O.O.
Exercices sur les pointeurs. lireCar/remettreCar Lorsque l’on lit caractère par caractère, on ne peut pas savoir qu’on a atteint un caractère avant de.
1 UNIX AVANCE Yves PAGNOTTE – Janvier – LES PROCESSUS SOUS UNIX.
Processus et threads.
Les structures de base Listes chainées. Listes Les listes(similaire aux tableaux) sont des structures informatiques qui permettent de garder en mémoire.
Transcription de la présentation:

jc/md/lp-01/06Synchronisation1

jc/md/lp-01/06Synchronisation2 Objectif du chapitre Création dune application ayant plusieurs threads Synchronisations entre threads –Section critique –Mutex –Événement –Sémaphore Exemples pratiques

jc/md/lp-01/06Synchronisation3 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.

jc/md/lp-01/06Synchronisation4 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

jc/md/lp-01/06Synchronisation5 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;

jc/md/lp-01/06Synchronisation6 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; }

jc/md/lp-01/06Synchronisation7 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; }

jc/md/lp-01/06Synchronisation8 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; }

jc/md/lp-01/06Synchronisation9 Résultat de lexécution

jc/md/lp-01/06Synchronisation10 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

jc/md/lp-01/06Synchronisation11 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é

jc/md/lp-01/06Synchronisation12 Section critique : fonctions (1) Initialisation dune section critique void InitializeCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); Entrée en section critique void EnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); Sortie dune section critique void LeaveCriticalSection( LPCRITICAL_SECTION lpCriticalSection );

jc/md/lp-01/06Synchronisation13 Section critique : fonctions (2) Restitution des ressources void DeleteCriticalSection( LPCRITICAL_SECTION lpCriticalSection ); Variante dentrée non bloquante BOOL TryEnterCriticalSection( LPCRITICAL_SECTION lpCriticalSection );

jc/md/lp-01/06Synchronisation14 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

jc/md/lp-01/06Synchronisation15 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;

jc/md/lp-01/06Synchronisation16 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; }

jc/md/lp-01/06Synchronisation17 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; }

jc/md/lp-01/06Synchronisation18 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; }

jc/md/lp-01/06Synchronisation19 Résultat de lexécution

jc/md/lp-01/06Synchronisation20 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é

jc/md/lp-01/06Synchronisation21 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.

jc/md/lp-01/06Synchronisation22 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

jc/md/lp-01/06Synchronisation23 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

jc/md/lp-01/06Synchronisation24 Application MUTEX Créer une application MUTEX Utiliser les mutexes pour que les textes ne soient plus mélangés lors de limpression

jc/md/lp-01/06Synchronisation25 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 );

jc/md/lp-01/06Synchronisation26 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; }

jc/md/lp-01/06Synchronisation27 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; }

jc/md/lp-01/06Synchronisation28 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; }

jc/md/lp-01/06Synchronisation29 Résultat de lexécution

jc/md/lp-01/06Synchronisation30 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

jc/md/lp-01/06Synchronisation31 Événements : fonctions (1) Création dun événement HANDLE 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

jc/md/lp-01/06Synchronisation32 Événements : fonctions (2) Ouverture dévénement HANDLE OpenEvent( DWORD dwDesiredAcess, BOOL bInheritHandle, LPCTSTR lpName); Fournit un handle sur un événement déjà créé par CreateEvent Correspondance par le nom lpName

jc/md/lp-01/06Synchronisation33 Événements : fonctions (3) Attente dévénement DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds); Activation de lévénement BOOL SetEvent(HANDLE hEvent); Désactivation de lévénement BOOL ResetEvent(HANDLE hEvent);

jc/md/lp-01/06Synchronisation34 Événements : fonctions (4) Dépôt dune donnée BOOL SetEventData(HANDLE hEvent, DWORD dwData); hEvent : handle de lévénement dwData : 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

jc/md/lp-01/06Synchronisation35 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

jc/md/lp-01/06Synchronisation36 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");

jc/md/lp-01/06Synchronisation37 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; }

jc/md/lp-01/06Synchronisation38 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; }

jc/md/lp-01/06Synchronisation39 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; }

jc/md/lp-01/06Synchronisation40 Résultat de lexécution

jc/md/lp-01/06Synchronisation41 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

jc/md/lp-01/06Synchronisation42 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)

jc/md/lp-01/06Synchronisation43 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);

jc/md/lp-01/06Synchronisation44 EVENT_NOM : main (3) Sleep(5000); CloseHandle(H1); CloseHandle(H2); CloseHandle(hEventA); CloseHandle(hEventB); printf("fin du main EVENT_NOM\n"); getchar(); return 0; }

jc/md/lp-01/06Synchronisation45 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);

jc/md/lp-01/06Synchronisation46 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; }

jc/md/lp-01/06Synchronisation47 EVENT_NOM : THREAD_A (3) ResetEvent(hEvent_A); SetEvent(hEvent_B); } printf("fin thread A\n"); return 0;

jc/md/lp-01/06Synchronisation48 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,p NomEventA); SetEventData(hEvent_A,2); hEvent_B=OpenEvent(EVENT_ALL_ACCESS,FALSE,p NomEventB); WaitForSingleObject(hEvent_B,INFINITE);

jc/md/lp-01/06Synchronisation49 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; }

jc/md/lp-01/06Synchronisation50 Résultat de lexécution

jc/md/lp-01/06Synchronisation51 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

jc/md/lp-01/06Synchronisation52 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

jc/md/lp-01/06Synchronisation53 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

jc/md/lp-01/06Synchronisation54 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

jc/md/lp-01/06Synchronisation55 Sémaphores : fonctions (3) WaitForSingleObject : déjà rencontrée BOOL ReleaseSemaphore( HANDLE hSemaphore, LONG lReleaseCount, LPLONG); –Arguments hSemaphore: handle fourni à la création lReleaseCount: nombre des jetons à restituer lpPreviousCount: pointeur sur une variable qui sera garnie par le compteur de jeton avant la mise à jour –Valeur de retour : réussite ou non

jc/md/lp-01/06Synchronisation56 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

jc/md/lp-01/06Synchronisation57 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");

jc/md/lp-01/06Synchronisation58 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; }

jc/md/lp-01/06Synchronisation59 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; }

jc/md/lp-01/06Synchronisation60 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; }

jc/md/lp-01/06Synchronisation61 Résultat de lexécution avec délai

jc/md/lp-01/06Synchronisation62 Résultat de lexécution sans délai

jc/md/lp-01/06Synchronisation63 Résultat de lexécution perturbée

jc/md/lp-01/06Synchronisation64 É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.

jc/md/lp-01/06Synchronisation65 Conclusion Les différentes méthodes de synchronisation ont été appliquées sur des exemples concrets