CreateSemaphore()

Syntax

Semaphore = CreateSemaphore([InitialCount])
Description
Creates a new semaphore object.

A semaphore is a thread synchronization object that keeps an internal count. It has two kinds of operations: signal and wait. A wait operation decreases the count of the semaphore by one. If the count would drop below 0, the wait operation will block until a signal call is made. A signal operation increases the count one, releasing a blocking thread if there is one. A semaphore allows to enforce minimum or maximum counts across threads for example to prevent a queue from running out or getting too many items.

Unlike a mutex, a semaphore object is not "owned" by a particular thread, which means that signal/wait calls do not need to be done from the same thread as it is the case with LockMutex() and UnlockMutex(). In fact a common use for a semaphore objects is for one thread to do the SignalSemaphore() calls and for another one to do all WaitSemaphore() calls to implement a producer/consumer pattern.

Parameters

InitialCount (optional) It has be a positive value that specifies the initial count of the semaphore. If it is not specified, the initial count is zero.

Return value

The new semaphore, or zero if the semaphore creation has failed.

Example

This example shows a "producer" thread populating a queue with elements and the main thread reading them. The semaphore is used to make sure the queue never runs out of elements. Note that this could also be achieved with only a mutex and waiting/polling for queue elements with a Delay() in between, but the semaphore commands do a more efficient wait (returning immediately at the SignalSemaphore() call and not just on the next time a polling loop would check the queue).
Global Semaphore = CreateSemaphore()
Global Mutex     = CreateMutex()
Global NewList Queue()

Procedure Producer(Total)

  For i = 1 To Total
    Delay(Random(750) + 250)
    
    ; The queue access still needs a normal mutex lock to be thread-safe
    LockMutex(Mutex)
      LastElement(Queue())
      AddElement(Queue())
      Queue() = i
    UnlockMutex(Mutex)    

    ; Signal that there is a new queue element
    SignalSemaphore(Semaphore)
  Next i
    
EndProcedure

If CreateThread(@Producer(), 30)

  For i = 1 To 30  
    ; wait for one element to be available
    WaitSemaphore(Semaphore)
    
    ; display the queue state
    LockMutex(Mutex)
      Queue$ = "Queue:"
      ForEach Queue()
        Queue$ + " " + Str(Queue())
      Next Queue()
      Debug Queue$
    
      ; remove head element from the queue
      FirstElement(Queue())
      DeleteElement(Queue())
    UnlockMutex(Mutex)
    
  Next i

EndIf

See Also

FreeSemaphore()

Supported OS

All

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