A semaphore is a synchronization primitive based on a counter that's decremented by each acquire() call and incremented by each release() call. If the counter ever reaches zero, the acquire() method blocks until some other thread calls release().
Creates a new semaphore. value is the initial value for the counter. If omitted, the counter is set to a value of 1.
A Semaphore instance, s, supports the following methods:
Acquires the semaphore. If the internal counter is larger than zero on entry, this method decrements it by 1 and returns immediately. If it's zero, this method blocks until another thread calls release(). The blocking argument has the same behavior as described for Lock and RLock objects.
Releases a semaphore by incrementing the internal counter by 1. If the counter is zero and another thread is waiting, that thread is awakened. If multiple threads are waiting, only one will be returned from its acquire() call.The order in which threads are released is not deterministic.
Creates a new semaphore. value is the initial value for the counter. If value is omitted, the counter is set to a value of 1.A BoundedSemaphore works exactly like a Semaphore except the number of release() operations cannot exceed the number of acquire() operations.
A subtle difference between a semaphore and a mutex lock is that a semaphore can be used for signaling. For example, the acquire() and release() methods can be called from different threads to communicate between producer and consumer threads.
produced = threading.Semaphore(O) consumed = threading.Semaphore(l)
def producer(): while True:
def consumer(): while True:
produced.acquire() item = get_item() consumed.release()
The kind of signaling shown in this example is often instead carried out using condition variables, which will be described shortly.
Was this article helpful?