Tutorial d'initiation A la programmation avec l'API Windows
Tutorial d'initiation a la programmation Windows avec Microsoft Visual C++
Chapitre 5Le multithreading12. Sémaphores
Cours théorique :
Les sémaphores sont utilisés pour limiter le nombre de threads en fonctionnement. Prenons le cas d'un serveur. On désire limiter le nombre maximal de connections simultanées. Dans ce cas, on utilisera la synchronisation fournie par les sémaphores.
Pour utiliser un sémaphore, une application doit créer une objet de type sémaphore en appelant la fonction CreateSemaphore(). Un sémaphore est constitué d'un compteur. Le statut d'un sémaphore est signalé lorsque le compteur est supérieur à 0 et non signalé lorsque le compteur est à 0. Lors de la création du sémaphore, on spécifie la valeur initiale du compteur, ainsi que sa valeur maximale. La valeur maximale du compteur correspond au nombre maximum de threads qui pourront être exécutés simultannément.
Chaque thread désirant se synchroniser doit utiliser une fonction d'attente (WaitForSingleObject() par exemple). Lorsqu'un thread appelant une fonction d'attente est libéré, le compteur du sémaphore est décrémenté de 1. Dès que la valeur du compteur atteint 0, les threads appelant les fonctions d'attente seront bloqués. Lorsqu'un thread sort d'un bloc synchronisé, il doit appeler la fonction ReleaseSemaphore(). Cette fonction incrémente de 1 le compteur du sémaphore, permettant ainsi à un autre thread d'être débloqué.
Le compteur du sémaphore ne pourra jamais dépasser la valeur maximale spécifiée au début. De cette manière, on peut très facilement limiter le nombre de threads effectuant une tâche spécifiée, et conserver ainsi les performances système. Une augmentation trop importante du nombre de threads en exécution simultanée poserait en effet des problèmes de performances.
Il est possible de spécifier un nom lors de la création du sémaphore. De cette manière, des applications différentes peuvent se synchroniser. La première crée un sémaphore nommé. La seconde application tente ensuite de créer un sémaphore du même nom. Ceci aura pour effet de lui retourner un HANDLE sur le sémaphore déjà existant. Le nom d'un sémaphore doit donc être unique dans l'ensemble du système. Remarquons qu'un sémaphore ne doit pas nécessairement être nommé.
|