threading.Condition()
для реализации условной переменной. Потоки используют acquire()
для блокировки и release()
для освобождения. wait()
блокирует поток и ждет уведомления, notify()
уведомляет один ждущий поток, а notify_all()
- все ждущие потоки. Важно вызывать wait()
, notify()
и notify_all()
только после захвата блокировки с помощью acquire()
.
`threading.Condition()` используется для организации сложных взаимодействий между потоками, когда одного лок-а не хватает. Он позволяет потокам засыпать (ждать) до тех пор, пока не будет выполнено определенное условие. Другие потоки, в свою очередь, могут сигнализировать об изменении этого условия, пробуждая ждущие потоки.
Основная идея заключается в следующем: поток, которому нужно дождаться определенного условия, вызывает метод `wait()` объекта `Condition()`. Этот метод атомарно освобождает связанный с `Condition()` лок-а и засыпает, ожидая сигнала. Другой поток, который изменяет состояние, влияющее на условие, вызывает метод `notify()` или `notify_all()` объекта `Condition()`. `notify()` пробуждает один ждущий поток (если есть), а `notify_all()` пробуждает все ждущие потоки.
Ключевые методы `threading.Condition()`:
Пример:
import threading
import time
class ProducerConsumer:
def __init__(self):
self.condition = threading.Condition()
self.buffer = []
self.buffer_size = 5
def produce(self):
while True:
with self.condition:
while len(self.buffer) == self.buffer_size:
print("Производитель: Буфер полон. Ожидаю...")
self.condition.wait() # Освобождаем лок-а и ждем
item = time.time() # Просто timestamp для примера
self.buffer.append(item)
print(f"Производитель: Произвел {item}")
self.condition.notify_all() # Уведомляем потребителей
time.sleep(1)
def consume(self):
while True:
with self.condition:
while len(self.buffer) == 0:
print("Потребитель: Буфер пуст. Ожидаю...")
self.condition.wait() # Освобождаем лок-а и ждем
item = self.buffer.pop(0)
print(f"Потребитель: Потребил {item}")
self.condition.notify_all() # Уведомляем производителей
time.sleep(2)
if __name__ == "__main__":
pc = ProducerConsumer()
producer_thread = threading.Thread(target=pc.produce)
consumer_thread = threading.Thread(target=pc.consume)
producer_thread.start()
consumer_thread.start()
producer_thread.join()
consumer_thread.join()
Объяснение примера:
Важные моменты:
`threading.Condition()` является мощным инструментом для синхронизации потоков в сложных сценариях, где простого лок-а недостаточно. Он позволяет потокам эффективно ждать определенных условий, не занимая процессорное время.