PureBasic

WaitSemaphore()

Синтаксис

WaitSemaphore(Semaphore)

Описание


Уменьшает внутренний счётчик Семафора на единицу, блокируя выполнение потока если счётчик достиг нуля. Заблокированный поток возобновляется как только другой поток вызовет функцию SignalSemaphore().

Параметры

Semaphore Номер, идентифицирующий объект Семафор, сигнал которого ожидается.

Возвращаемое значение

Ничего.

Комментарии

Примечание: Счётчик Семафора ограничен знаковым 32-битным значением, поэтому можно сделать максимум 2147483647 вызовов функции WaitSemaphore(), каждый из которых будет сбалансирован вызовом функции SignalSemaphore().

Пример

Этот пример показывает поток "производитель", заполняющий очередь элементами, и главный поток, читающий их. Семафор используется чтобы гарантировать, что очередь никогда не опустеет. Заметьте, того же можно добиться с помощью только Мьютекса и операций ожидания/опроса очереди вперемежку с вызовами функции Delay(), но команды Семафора реализуют более эффективное ожидание (возвращаясь сразу из вызова функции SignalSemaphore(), а не в следующий раз, когда цикл опроса проверит очередь).
Global Semaphore = CreateSemaphore()
Global Mutex     = CreateMutex()
Global NewList Queue()

Procedure Producer(Total)

  For i = 1 To Total
    Delay(Random(750) + 250)
    
    ; Работа с очередью всё же требует нормальной блокировки через Мьютекс для потокобезопасности
    LockMutex(Mutex)
      LastElement(Queue())
      AddElement(Queue())
      Queue() = i
    UnlockMutex(Mutex)    

    ; Сигнализируем, что в очереди новый элемент
    SignalSemaphore(Semaphore)
  Next i
    
EndProcedure

If CreateThread(@Producer(), 30)

  For i = 1 To 30  
    ; ожидаем наличия одного элемента
    WaitSemaphore(Semaphore)
    
    ; отображаем состояние очереди
    LockMutex(Mutex)
      Queue$ = "Queue:"
      ForEach Queue()
        Queue$ + " " + Str(Queue())
      Next Queue()
      Debug Queue$
    
      ; удаляем головной элемент из очереди
      FirstElement(Queue())
      DeleteElement(Queue())
    UnlockMutex(Mutex)
    
  Next i

EndIf

Поддерживаемые OS

Все

<- UnlockMutex() - Оглавление Thread - WaitThread()->