Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between .Semaphore() and .BoundedSemaphore()?

I know that threading.Lock() is equal to threading.Semaphore(1).

Is also threading.Lock() equal to threading.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)
like image 769
Benyamin Jafari Avatar asked Sep 05 '25 03:09

Benyamin Jafari


2 Answers

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.')    
like image 154
Don Kirkby Avatar answered Sep 07 '25 19:09

Don Kirkby


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.

like image 44
Vivek Kalyanarangan Avatar answered Sep 07 '25 20:09

Vivek Kalyanarangan