Найти в Дзене
programmer's notes (python and more)

Программирование на Python. Многозадачность. Синхронизация потоков с помощью событий (Event)

Доброго времени суток, читатели, зрители моего канала programmer's notes. Не забывайте подписываться и писать свои комментарии к моим статьям и видео.

Статья является продолжением статей по многозадачности потоков с использованием библиотеки threding. См. также

и предыдущую статью по Event

Подробнее о классе Event

В данной статье более подробно остановимся на класса Event библиотеки threading.

Объект, создаваемый threading.Event() обладает двумя состояниями: True и False. При создании объекта он автоматически устанавливается в состояние False. Событием можно назвать его переход в состояние True. Такой переход может использоваться как спусковой крючок для выполнения того или иного действия со стороны потоков.

Рассмотрим методы объекта класса Event.

  • is_set() — метод возвращает состояние объекта Event, т.е. True или False.
  • set() — метод устанавливает состояние объекта в True.
  • clear() — метод устанавливает состояние объекта в False.
  • wait(timeout=None) — ожидает, когда объект Event перейдёт в состояние True. Если установлен timeout то метод ожидает установленное количество времени. Значение timeout может иметь значение float.

Рассмотрим пример программы. В программе три потока. Один поток рекурсивно обходит дерево каталогов и помещает полное имя файла в очередь. Два других потока по очереди берут из потока элемент, проверяют нет ли в имени файла заданной строки и если есть, то помещают имя файла в файл temp.

Поскольку программа большая, то она разбита на три скриншота, но ниже дана ссылка на полный текст программа на github.

Фрагмент 1 программы
Фрагмент 1 программы
Фрагмент 2 программ
Фрагмент 2 программ
Фрагмент 3 программы. Ниже ссылка на полный текст программы
Фрагмент 3 программы. Ниже ссылка на полный текст программы
primer119.py

Дадим несколько пояснений к программе.

  • Поток на основе функции search() осуществляет рекурсивный поиск по файловой системе и помещает полные пути к найденным файлам в очередь.
  • Два потока на основе функции reading() по очереди берут из очереди полный путь к файлу, выделяют имя файла и проверяют есть ли в имени файла заданная строка. Если строка присутствует, то потоки помещают имя файла в файл temp.
  • Файл для записи имён файлов открывается в основной программе, дескриптор файла является глобальным объектом.
  • В основной программе создаётся два события Event. Созданные объекты передаются в потоки, читающие из очереди, в качестве параметров, по одному на каждый поток.
  • В основной программе периодически проверяется не закончил ли работу поток, осуществляющий поиск файлов. Как только поток заканчивает работу, устанавливаются флаги событий ev1 и ev2, что приводит к окончанию работы двух других потоков.
  • особо отметим строку s1 = os.path.basename(q.get(block=False)). Метод get() или возвращает элемент из очереди или вызывает исключение. Это важнейший момент. Если использовать block=True (по умолчанию), то в конце выполнения программы, может произойти зависание: один из потоков будет бесконечно долго ждать появление элемента в пустой очереди.

Хорошего программирования. Оставляйте свои комментарии, не забывайте про лайки и подписывайтесь на мой канал programmer's notes.

"Да не омрачат поток вашего сознания никакие события" - вежливая форма обращения восточных программистов
"Да не омрачат поток вашего сознания никакие события" - вежливая форма обращения восточных программистов