#python #multithreading #events #timer #busy-waiting
#python #многопоточность #Мероприятия #таймер #занято -ожидание
Вопрос:
В настоящее время я создаю приложение на python, которое должно запускать функции в заданных временных метках, введенных пользователем (не введенных в хронологическом порядке).
Я столкнулся с проблемой, потому что я не хочу, чтобы моя программа была занята — ожидание проверки, введена ли новая временная метка, которая должна быть добавлена в очередь таймера, но также не создает целую кучу потоков для каждого создания новой временной метки с единственной целью ожидания этой временной метки.
Я подумал о том, чтобы собрать все это в одном потоке и сделать что-то вроде прерываемого сна, но я не могу придумать другого способа, кроме этого:
while timer_not_depleted:
sleep(1)
if something_happened:
break
который, по сути, занят ожиданием.
Итак, есть какие-либо предложения по реализации прерываемого сна?
Ответ №1:
Ваша интуиция использования потоков верна. Может работать следующая конструкция master-worker:
- Главный поток порождает рабочий поток, который ожидает «заданий»;
- Два потока совместно
Queue
используют — всякий раз, когда необходимо запланировать новое задание, главный потокput
помещает спецификацию задания в очередь; - Между тем, рабочий поток выполняет следующее:
- Поддерживайте отдельный список будущих заданий для запуска и отслеживайте, как долго сохранять режим ожидания до запуска следующего задания;
- Продолжайте прослушивать новые задания, вызывая
Queue.get(block=True, timeout=<time-to-next-job>)
; - В этом случае, если до истечения времени ожидания не запланировано никаких новых заданий,
Queue.get
возникнетEmpty
исключение — и в этот момент рабочий поток должен запустить запланированную функцию и вернуться к опросу. Если тем временем запланировано новое задание,Queue.get
возвращает новое задание, чтобы вы могли обновитьtimeout
значение, а затем вернуться к ожиданию.
Комментарии:
1. После некоторого кодирования это выглядит очень многообещающе, так что спасибо 🙂
Ответ №2:
Я хотел бы предложить выбрать.
Вызовите его с таймаутом, равным задержке до ближайшего события (очередь кучи — хорошая структура данных для поддержания очереди будущих временных меток) и предоставьте сокет (как элемент в rlist
аргументе), где ваша программа прослушивает обновления от пользователя.
select
Вызов возвращается, когда сокет получает входящие данные или когда истекло время ожидания.