What is the difference between .Semaphore() and .BoundedSemaphore()?
Solution 1
A Semaphore
can be released more times than it's acquired, and that will raise its counter above the starting value. A BoundedSemaphore
can't be raised above the starting value.
from threading import Semaphore, BoundedSemaphore
# Usually, you create a Semaphore that will allow a certain number of threads
# into a section of code. This one starts at 5.
s1 = Semaphore(5)
# When you want to enter the section of code, you acquire it first.
# That lowers it to 4. (Four more threads could enter this section.)
s1.acquire()
# Then you do whatever sensitive thing needed to be restricted to five threads.
# When you're finished, you release the semaphore, and it goes back to 5.
s1.release()
# That's all fine, but you can also release it without acquiring it first.
s1.release()
# The counter is now 6! That might make sense in some situations, but not in most.
print(s1._value) # => 6
# If that doesn't make sense in your situation, use a BoundedSemaphore.
s2 = BoundedSemaphore(5) # Start at 5.
s2.acquire() # Lower to 4.
s2.release() # Go back to 5.
try:
s2.release() # Try to raise to 6, above starting value.
except ValueError:
print('As expected, it complained.')
Solution 2
The threading module provides the simple Semaphore
class.
A Semaphore
provides a non-bounded counter which allows you to call release()
any number of times for incrementing.
However, to avoid programming errors, it’s usually a correct choice to use BoundedSemaphore
, which raises an error if a release()
call tries to increase the counter beyond its maximum size.
EDIT
A semaphore has an internal counter rather than a lock flag (in case of Locks), and it only blocks if more than a given number of threads have attempted to hold the semaphore. Depending on how the semaphore is initialized, this allows multiple threads to access the same code section simultaneously.
Benyamin Jafari - aGn
⋆I've studied at NODET High School. ⋆B.Sc. in Software Engineering at QIAU University. ⋆M.Sc. in Mechatronic Engineering from QIAU University. ⋆I used to do R&D at Mechatronics Research Laboratory (MRL) in the @Home team. ⋆Python/Django Backend Developer at Arta Vision Ava – Data Center Infrastructure Management (IVMS | DCIM). ⋆Machine Learning and Robotics enthusiast, especially Deep Learning and Self-Driving Cars. Tokens of appreciation are very welcome if you've appreciated my assistance: ⋆BTC Donations: bc1qw7x5yk7cmu2kg5wutalwf58z0mttcckj8w0av2 ⋆ETH Donations: 0xA892c4bd5509E2549f74A0f8405279CCDA4A69De ⋆TRX Donations: TJUngJzu2oRPqtT9KDtJAcBVepdJofsnbd ⋆TOMO Donations: 0xB2C87EF5243cF7aCD715B87c482E0c743B270a91
Updated on June 21, 2022Comments
-
Benyamin Jafari - aGn almost 2 years
I know that
threading.Lock()
is equal tothreading.Semaphore(1)
.Is also
threading.Lock()
equal tothreading.BoundedSemaphore(1)
?And newly I saw
threading.BoundedSemaphore()
, what is the difference between them? For example in the following code snippet (applying limitation on threads):import threading sem = threading.Semaphore(5) sem = threading.BoundedSemaphore(5)