все Python 3threadingпонятие
threading.BoundedSemaphore
синхронизация
Семафор, который не даёт счётчику превысить начальное значение: лишний release() поднимает ValueError, а не расширяет лимит молча.
Синтаксис
sem = threading.BoundedSemaphore(value=1)
with sem: ...
Обычный Semaphore позволяет вызвать release() больше раз, чем acquire(): счётчик растёт, и ограничение «не больше N одновременно» тихо перестаёт действовать. BoundedSemaphore ловит такую ошибку в месте её появления. Берите его, когда семафор охраняет ресурс с жёстким лимитом — пул соединений, число одновременных загрузок: лишний release там всегда баг. А пару acquire/release надёжнее всего держит with.
Примеры
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
См. также
Частые ошибки
Открыть в полном глоссарииdocs.python.orgСообщить о неточности