all Python 3threadingterm
threading.BoundedSemaphore
synchronization
A semaphore that never lets its counter exceed the initial value: an extra release() raises ValueError instead of silently widening the limit.
Syntax
sem = threading.BoundedSemaphore(value=1)
with sem: ...
A plain Semaphore lets you call release() more times than acquire(): the counter grows and the 'at most N at once' limit quietly stops working. BoundedSemaphore catches that mistake where it happens. Use it whenever the semaphore guards a resource with a hard limit — a connection pool, a number of parallel downloads: an extra release there is always a bug. A with block keeps acquire and release paired most reliably.
Examples
import threading
pool = threading.BoundedSemaphore(2)
with pool:
pass
try:
pool.release() # лишний release
except ValueError as e:
print(e) # → Semaphore released too many times
import threading
import time
slots = threading.BoundedSemaphore(2)
lock = threading.Lock()
active = peak = 0
def download():
global active, peak
with slots:
with lock:
active += 1
peak = max(peak, active)
time.sleep(0.02)
with lock:
active -= 1
threads = [threading.Thread(target=download) for _ in range(6)]
for t in threads:
t.start()
for t in threads:
t.join()
print(peak <= 2) # → True
See also
Common errors
Open in the full glossarydocs.python.orgReport an inaccuracy