Как использовать `threading.Event()` для синхронизации потоков?

Событие threading.Event() используется для сигнализации между потоками.
  • .set(): Устанавливает внутренний флаг события в True, разблокируя все ожидающие потоки.
  • .clear(): Сбрасывает флаг в False, блокируя последующие .wait() вызовы.
  • .wait([timeout]): Блокирует поток, пока флаг не станет True (или истечет таймаут).
  • Пример: Один поток устанавливает событие, сигнализируя другим, что они могут начать/продолжить работу.

threading.Event() - это простой способ сигнализировать между потоками в Python. Он позволяет одному или нескольким потокам ждать, пока другой поток не установит флаг события.

Основные методы:

  • Event(): Конструктор, создает объект события. Изначально внутренний флаг установлен в False.
  • set(): Устанавливает внутренний флаг события в True. Все потоки, которые ожидают события (через wait()), будут разблокированы.
  • clear(): Сбрасывает внутренний флаг события в False. Потоки, ожидающие события, будут заблокированы, пока флаг снова не будет установлен.
  • wait(timeout=None): Блокирует вызывающий поток до тех пор, пока внутренний флаг события не станет True или не истечет необязательный тайм-аут. Возвращает True, если событие было установлено до истечения тайм-аута, и False в противном случае. Если тайм-аут не указан, поток блокируется бесконечно.
  • is_set(): Возвращает True, если внутренний флаг установлен, и False в противном случае.

Пример использования:


import threading
import time

def worker(event, worker_id):
    print(f"Поток {worker_id}: Жду события...")
    event.wait() # Блокирует поток до тех пор, пока event.set() не будет вызван
    print(f"Поток {worker_id}: Событие произошло! Продолжаю работу...")

def main():
    event = threading.Event()

    # Создаем и запускаем несколько потоков-работников
    threads = []
    for i in range(3):
        thread = threading.Thread(target=worker, args=(event, i))
        threads.append(thread)
        thread.start()

    # Ждем немного времени
    time.sleep(2)

    # Устанавливаем событие
    print("Основной поток: Устанавливаю событие...")
    event.set() # Разблокирует все потоки, ждущие события

    # Ждем завершения потоков
    for thread in threads:
        thread.join()

    print("Основной поток: Все потоки завершили работу.")

if __name__ == "__main__":
    main()
  

Описание примера:

  • Функция worker представляет поток, который ждет установки события с помощью event.wait().
  • Основной поток создает объект Event и запускает несколько потоков-работников.
  • Потоки-работники блокируются в ожидании события.
  • Основной поток ждет 2 секунды, а затем вызывает event.set(), чтобы установить событие.
  • Установка события разблокирует все потоки, которые ожидают события, и они продолжают свою работу.
  • Наконец, основной поток ждет завершения всех потоков-работников с помощью thread.join().

Применение:

threading.Event() полезен в ситуациях, когда один или несколько потоков должны ожидать определенного события, прежде чем продолжить свою работу. Например:

  • Ожидание завершения инициализации ресурса перед началом его использования.
  • Ожидание получения данных от другого потока.
  • Синхронизация нескольких потоков для совместной работы.
  • Запуск группы потоков одновременно после короткой паузы.

В целом, threading.Event() - это простой и эффективный способ синхронизации потоков в Python, особенно когда требуется односторонняя сигнализация (один поток сигнализирует другим).

0