Прерываемый сон?

#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 Вызов возвращается, когда сокет получает входящие данные или когда истекло время ожидания.