Содержание страницы
18.5.2. Циклы событий¶Event loops
Исходный код: Lib/asyncio/events.py
18.5.2.1. Функции цикла событий¶Event loop functions
Следующие функции представляют собой удобные сокращения для доступа к методам
gлобальной политики. Обратите внимание, что это обеспечивает доступ к политике по умолчанию, если только альтернативная политика не была установлена вызовом set_event_loop_policy() ранее
в процессе выполнения программы.
-
asyncio.get_event_loop()¶ Эквивалентно вызову
get_event_loop_policy().get_event_loop().
-
asyncio.set_event_loop(loop)¶ Эквивалентно вызову
get_event_loop_policy().set_event_loop(loop).
-
asyncio.new_event_loop()¶ Эквивалентно вызову
get_event_loop_policy().new_event_loop().
18.5.2.2. Доступные циклы событий¶Available event loops
asyncio в настоящее время предоставляет две реализации циклов событий:
SelectorEventLoop и ProactorEventLoop.
-
class
asyncio.SelectorEventLoop¶ Цикл событий, основанный на модуле
selectors. ПодклассAbstractEventLoop.Использует самый эффективный селектор, доступный на платформе.
В Windows поддерживаются только сокеты (например, каналы не поддерживаются): см. документацию MSDN по select.
-
class
asyncio.ProactorEventLoop¶ Proactor-цикл событий для Windows, использующий «I/O Completion Ports» (также известные как IOCP). Подкласс
AbstractEventLoop.Доступность: Windows.
Пример использования ProactorEventLoop в Windows:
import asyncio, sys
if sys.platform == 'win32':
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
18.5.2.3. Поддержка платформ¶Platform support
Модуль asyncio разработан как переносимый, но каждая платформа
имеет свои тонкие различия и может не поддерживать все возможности asyncio.
18.5.2.3.1. Windows¶
Общие ограничения циклов событий Windows:
create_unix_connection()иcreate_unix_server()не поддерживаются: семейство сокетовsocket.AF_UNIXспецифично для UNIXadd_signal_handler()иremove_signal_handler()не поддерживаютсяEventLoopPolicy.set_child_watcher()не поддерживается.ProactorEventLoopподдерживает подпроцессы. У него есть только одна реализация для наблюдения за дочерними процессами, настраивать её не нужно.
SelectorEventLoopСпецифические ограничения:
SelectSelectorиспользуется, он поддерживает только сокеты и ограничен 512 сокетами.add_reader()иadd_writer()принимают только файловые дескрипторы сокетовКаналы не поддерживаются (например:
connect_read_pipe(),connect_write_pipe())Подпроцессы не поддерживаются (например:
subprocess_exec(),subprocess_shell())
ProactorEventLoopСпецифические ограничения:
create_datagram_endpoint()(UDP) не поддерживается.add_reader()иadd_writer()не поддерживаются.
Разрешение монотонных часов в Windows обычно составляет около 15,6 мс. Наилучшее разрешение – 0,5 мс. Разрешение зависит от оборудования (наличие HPET) и от конфигурации Windows. См. отложенные вызовы asyncio.
Изменено в версии 3.5: ProactorEventLoop теперь поддерживает SSL.
18.5.2.3.2. Mac OS X¶
Символьные устройства, такие как PTY, хорошо поддерживаются только начиная с Mavericks (Mac OS 10.9). Они вообще не поддерживаются на Mac OS 10.5 и старше.
На Mac OS 10.6, 10.7 и 10.8 цикл событий по умолчанию – это
SelectorEventLoop, который использует selectors.KqueueSelector.
selectors.KqueueSelector не поддерживает символьные устройства на этих
версиях. SelectorEventLoop можно использовать с
SelectSelector или PollSelector для
поддержки символьных устройств на этих версиях Mac OS X. Пример:
import asyncio
import selectors
selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)
18.5.2.4. Политики цикла событий и политика по умолчанию¶Event loop policies and the default policy
Управление циклом событий абстрагируется с помощью шаблона политика, чтобы обеспечить максимальную
гибкость для нестандартных платформ и фреймворков. В ходе выполнения
процесса единственный глобальный объект политики управляет циклами событий, доступными
процессу, в зависимости от контекста вызова. Политика – это объект, реализующий
интерфейс AbstractEventLoopPolicy.
Для большинства пользователей asyncio с политиками никогда не приходится
явно иметь дело, поскольку глобальной политики по умолчанию достаточно (см. ниже).
Функции уровня модуля
get_event_loop() и set_event_loop() предоставляют удобный доступ к
циклам событий, управляемым политикой по умолчанию.
18.5.2.5. Интерфейс политики цикла событий¶Event loop policy interface
Политика цикла событий должна реализовывать следующий интерфейс:
-
class
asyncio.AbstractEventLoopPolicy¶ Политика цикла событий.
-
get_event_loop()¶ Возвращает цикл событий для текущего контекста.
Возвращает объект цикла событий, реализующий интерфейс
AbstractEventLoop. При вызове из корутины возвращает текущий выполняющийся цикл событий.Вызывает исключение, если для текущего контекста не задан цикл событий и текущая политика не предписывает его создать. Он никогда не должен возвращать
None.Изменено в версии 3.6.
-
set_event_loop(loop)¶ Устанавливает цикл событий для текущего контекста равным loop.
-
new_event_loop()¶ Создаёт и возвращает новый объект цикла событий в соответствии с правилами этой политики.
Если необходимо установить этот цикл в качестве цикла событий для текущего контекста,
set_event_loop()должен быть вызван явно.
-
Политика по умолчанию определяет контекст как текущий поток и управляет циклом
событий для каждого потока, который взаимодействует с asyncio. Если с текущим потоком
ещё не связан цикл событий, метод get_event_loop() политики по умолчанию создаёт его при
вызове из главного потока, но в противном случае вызывает RuntimeError.
18.5.2.6. Доступ к глобальной политике цикла событий¶Access to the global loop policy
-
asyncio.get_event_loop_policy()¶ Возвращает текущую политику цикла событий.
-
asyncio.set_event_loop_policy(policy)¶ Устанавливает текущую политику цикла событий. Если политика равна
None, восстанавливается политика по умолчанию.
18.5.2.7. Настройка политики цикла событий¶Customizing the event loop policy
Чтобы реализовать новую политику цикла событий, рекомендуется создать подкласс
конкретной политики цикла событий по умолчанию DefaultEventLoopPolicy
и переопределить методы, поведение которых требуется изменить, например:
class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
def get_event_loop(self):
"""Получить цикл событий.
Это может быть None или экземпляр EventLoop.
"""
loop = super().get_event_loop()
# Сделать что-то с циклом ...
return loop
asyncio.set_event_loop_policy(MyEventLoopPolicy())