CreateSemaphore()
Syntaxe
Resultat = CreateSemaphore([CompteurInitial])Description
Crée un nouveau sémaphore.
Arguments
CompteurInitial (optionnel) Ce 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.
Valeur de retour
Renvoie le nouveau sémaphore, ou zéro en cas d'échec.
Remarques
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). Un sémaphore permet d'appliquer un comptage minimum et maximum entre les threads par exemple pour éviter à la file d'attente de manquer d'éléments ou au contraire d'en avoir trop.
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 à mesure que des éléments sont
ajoutés. Le sémaphore permet au thread
principal de se mettre en attente 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
Voir aussi
FreeSemaphore()
OS Supportés
Tous