CreateSemaphore()
Syntaxe
Semaphore = CreateSemaphore([CompteurInitial])Description
Crée un nouveau sémaphore. Le paramètre optionnel 'CompteurInitial' doit être une valeur positive qui indique le compteur initial du sémaphore. S'il n'est pas spécifié, le compteur initial vaudra 0.
Un sémaphore est un objet de synchronisation de threads, qui contient un compteur interne. Il gère deux types d'opérations: attente et signalement. L'opération d'attente diminue la valeur du compteur du sémaphore de un. Si le compteur devait passer à une valeur inférieure à 0, l'opération d'attente sera bloquante, jusqu'à ce qu'une opération de signalement soit faite. Cette dernière augmente la valeur du compteur de un, libérant le thread bloqué (si il y en a un).
Contrairement à un mutex, un sémaphore n'appartient pas à un thread particulier, ce qui permet aux opérations d'attente/signalement d'être effectuées depuis n'importe quel thread, ce qui n'est pas le cas de LockMutex() et UnlockMutex(). Une utilisation courante des sémaphores est la création d'un thread qui attend sur le sémaphore avec WaitSemaphore() et d'un autre qui le débloque avec SignalSemaphore(): c'est le pattern producteur/consommateur.
Exemple
Cet exemple montre un thread "producteur" qui ajoute des éléments à une liste et un thread principal qui affiche la liste
au fur et à messure que des éléments sont ajoutés. Le sémaphore permet au thread principal de se mettre en attendre si la liste ne contient
aucun élément. A noter que cela aurait pu aussi être effectué avec un mutex, en testant à intervalle régulier si
la liste est vide ou non (en utilisant Delay()). Le sémaphore est bien plus efficace, car il débloque
immédiatemment le thread lorsque le signalement est effectué, et élimine l'intervalle d'attente.
; Assurez vous que l'option "Activer la gestion des threads" est sélectionnée
;
Global Semaphore = CreateSemaphore()
Global Mutex = CreateMutex()
Global NewList Queue()
Procedure Producer(Total)
For i = 1 To Total
Delay(Random(750) + 250)
; L'accès à la liste nécessite tout de même un mutex pour être threadsafe
LockMutex(Mutex)
LastElement(Queue())
AddElement(Queue())
Queue() = i
UnlockMutex(Mutex)
; Envoie un signal pour indiquer qu'un nouvel élément est disponible
SignalSemaphore(Semaphore)
Next i
EndProcedure
If CreateThread(@Producer(), 30)
For i = 1 To 30
; Attente d'un nouvel élément
WaitSemaphore(Semaphore)
; Affiche l'état de la liste
LockMutex(Mutex)
Queue$ = "Queue:"
ForEach Queue()
Queue$ + " " + Str(Queue())
Next Queue()
Debug Queue$
; Efface le premier élément de la liste
FirstElement(Queue())
DeleteElement(Queue())
UnlockMutex(Mutex)
Next i
EndIf
OS Supportés
Tous