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.
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.
The new semaphore, or zero if the semaphore creation has failed.
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