Автор оригинала: Doug Hellmann.
Цель:
Планировщик общих событий.
Модуль sched
реализует общий планировщик событий для выполнения задач в определенное время. Класс планировщика использует функцию time
для определения текущего времени и функцию delay
для ожидания определенного периода времени. Фактические единицы времени не важны, что делает интерфейс достаточно гибким для использования во многих целях.
Функция time
вызывается без аргументов и должна возвращать число, представляющее текущее время. Функция delay
вызывается с одним целочисленным аргументом, использует тот же масштаб, что и функция времени, и должна ждать столько единиц времени, прежде чем вернуться. По умолчанию используются monotonic ()
и sleep ()
от времени, но в примерах в этом разделе используется time.time ()
, который также соответствует требованиям, поскольку делает вывод более понятным.
Для поддержки многопоточных приложений функция задержки вызывается с аргументом 0 после генерации каждого события, чтобы гарантировать, что другие потоки также имеют возможность работать.
Запуск событий с задержкой
События могут быть запланированы на запуск после задержки или в определенное время. Чтобы запланировать их с задержкой, используйте метод enter ()
, который принимает четыре аргумента.
- Число, представляющее задержку
- Приоритетное значение
- Функция для вызова
- Набор аргументов функции
В этом примере планируется запуск двух разных событий через две и три секунды соответственно. Когда наступает время события, вызывается print_event ()
и печатает текущее время и аргумент имени, переданный событию.
sched_basic.py
import sched import time scheduler sched.scheduler(time.time, time.sleep) def print_event(name, start): now time.time() elapsed int(now - start) print('EVENT: {}>{}>{}'.format( time.ctime(now), elapsed, name)) start time.time() print('START:', time.ctime(start)) scheduler.enter(2, 1, print_event, ('first', start)) scheduler.enter(3, 1, print_event, ('second', start)) scheduler.run()
Запуск программы производит:
$ python3 sched_basic.py START: Sun Sep 4 16:21:01 2016 EVENT: Sun Sep 4 16:21:03 2016 elapsed=2 EVENT: Sun Sep 4 16:21:04 2016 elapsed=3
Время, напечатанное для первого события, составляет две секунды после запуска, а время для второго события – три секунды после запуска.
Перекрывающиеся события
Вызов run ()
блокируется до тех пор, пока все события не будут обработаны. Каждое событие запускается в одном потоке, поэтому, если для выполнения события требуется больше времени, чем задержка между событиями, произойдет перекрытие. Наложение разрешается путем откладывания более позднего мероприятия. События не теряются, но некоторые события могут быть вызваны позже, чем было запланировано. В следующем примере long_event ()
находится в спящем режиме, но он может так же легко задержаться, выполняя длительные вычисления или блокируя ввод-вывод.
sched_overlap.py
import sched import time scheduler sched.scheduler(time.time, time.sleep) def long_event(name): print('BEGIN EVENT :', time.ctime(time.time()), name) time.sleep(2) print('FINISH EVENT:', time.ctime(time.time()), name) print('START:', time.ctime(time.time())) scheduler.enter(2, 1, long_event, ('first',)) scheduler.enter(3, 1, long_event, ('second',)) scheduler.run()
В результате второе событие запускается сразу после завершения первого, поскольку первое событие заняло достаточно времени, чтобы часы прошли желаемое время начала второго события.
$ python3 sched_overlap.py START: Sun Sep 4 16:21:04 2016 BEGIN EVENT : Sun Sep 4 16:21:06 2016 first FINISH EVENT: Sun Sep 4 16:21:08 2016 first BEGIN EVENT : Sun Sep 4 16:21:08 2016 second FINISH EVENT: Sun Sep 4 16:21:10 2016 second
Приоритеты событий
Если на одно и то же время запланировано более одного события, их значения приоритета используются для определения порядка их запуска.
sched_priority.py
import sched import time scheduler sched.scheduler(time.time, time.sleep) def print_event(name): print('EVENT:', time.ctime(time.time()), name) now time.time() print('START:', time.ctime(now)) scheduler.enterabs(now + 2, 2, print_event, ('first',)) scheduler.enterabs(now + 2, 1, print_event, ('second',)) scheduler.run()
В этом примере необходимо убедиться, что они запланированы на одно и то же время, поэтому вместо enter ()
используется метод enterabs ()
. Первый аргумент функции enterabs ()
– это время запуска события, а не время задержки.
$ python3 sched_priority.py START: Sun Sep 4 16:21:10 2016 EVENT: Sun Sep 4 16:21:12 2016 second EVENT: Sun Sep 4 16:21:12 2016 first
Отмена событий
И enter ()
, и enterabs ()
возвращают ссылку на событие, которую можно использовать для его отмены позже. Поскольку run ()
блокируется, событие необходимо отменить в другом потоке. В этом примере запускается поток для запуска планировщика, а основной поток обработки используется для отмены события.
sched_cancel.py
import sched import threading import time scheduler sched.scheduler(time.time, time.sleep) # Set up a global to be modified by the threads counter 0 def increment_counter(name): global counter print('EVENT:', time.ctime(time.time()), name) counter 1 print('NOW:', counter) print('START:', time.ctime(time.time())) e1 scheduler.enter(2, 1, increment_counter, ('E1',)) e2 scheduler.enter(3, 1, increment_counter, ('E2',)) # Start a thread to run the events t threading.Thread(targetscheduler.run) t.start() # Back in the main thread, cancel the first scheduled event. scheduler.cancel(e1) # Wait for the scheduler to finish running in the thread t.join() print('FINAL:', counter)
Было запланировано два мероприятия, но первое позже было отменено. Выполняется только второе событие, поэтому переменная счетчика увеличивается только один раз.
$ python3 sched_cancel.py START: Sun Sep 4 16:21:13 2016 EVENT: Sun Sep 4 16:21:16 2016 E2 NOW: 1 FINAL: 1
Смотрите также
- стандартная библиотека документации для расписания
- time – модуль
time
.