все Python 3threadingпонятие
threading.Condition
синхронизация
Условная переменная: поток ждёт в wait(), пока другой не изменит общее состояние и не вызовет notify(). Основа схемы «производитель — потребитель».
Синтаксис
cond = threading.Condition(lock=None)
with cond: cond.wait_for(predicate, timeout=None)
with cond: cond.notify(n=1) / cond.notify_all()
wait() и notify() работают только под захваченной блокировкой условия (with cond:), иначе RuntimeError. Пробуждение не гарантирует, что нужное состояние наступило — другой поток мог успеть первым, — поэтому проверку пишут в цикле while или зовут wait_for(predicate), который крутит этот цикл сам. notify(), вызванный раньше, чем кто-то начал ждать, теряется: в отличие от Event, условие ничего не запоминает, помнит только ваше состояние. Для простой передачи данных между потоками удобнее queue.Queue — она построена на тех же Condition.
Примеры
import threading
cond = threading.Condition()
items, result = [], []
def producer():
for i in range(3):
with cond:
items.append(i)
cond.notify()
def consumer():
with cond:
cond.wait_for(lambda: len(items) == 3, timeout=1)
result.append(list(items))
c = threading.Thread(target=consumer)
p = threading.Thread(target=producer)
c.start()
p.start()
c.join()
p.join()
print(result) # → [[0, 1, 2]]
import threading
cond = threading.Condition()
try:
cond.notify() # блокировка условия не захвачена
except RuntimeError as e:
print(e) # → cannot notify on un-acquired lock
См. также
Частые ошибки
Открыть в полном глоссарииdocs.python.orgСообщить о неточности