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

<- CreateMutex() - Thread Index - CreateThread() ->