Перейти к содержимому

18.5.2. Циклы событий

Исходный код: Lib/asyncio/events.py

18.5.2.1. Функции цикла событий

Следующие функции являются удобными сокращениями для доступа к методам глобальной политики. Обратите внимание, что это обеспечивает доступ к политике по умолчанию, если только альтернативная политика не была задана вызовом set_event_loop_policy() ранее в ходе выполнения процесса.

asyncio.get_event_loop()

Эквивалентно вызову get_event_loop_policy().get_event_loop().

asyncio.set_event_loop(цикл событий)

Эквивалентно вызову get_event_loop_policy().set_event_loop(loop).

asyncio.new_event_loop()

Эквивалентно вызову get_event_loop_policy().new_event_loop().

18.5.2.2. Доступные циклы событий

asyncio в настоящее время предоставляет две реализации циклов событий: SelectorEventLoop и ProactorEventLoop.

classasyncio.SelectorEventLoop

Цикл событий на основе модуля selectors. Подкласс AbstractEventLoop.

Использует наиболее эффективный селектор, доступный на платформе.

В Windows поддерживаются только сокеты (например, каналы не поддерживаются): см. документацию MSDN по select.

classasyncio.ProactorEventLoop

Proactor-цикл событий для Windows, использующий «порты завершения ввода-вывода» (IOCP). Подкласс AbstractEventLoop.

Доступность: Windows.

Пример использования ProactorEventLoop в Windows:

python
import asyncio, sys

if sys.platform == 'win32':
    loop = asyncio.ProactorEventLoop()
    asyncio.set_event_loop(loop)

18.5.2.3. Поддержка платформ

Модуль asyncio спроектирован переносимым, но каждая платформа имеет свои тонкие отличия и может не поддерживать все возможности asyncio.

18.5.2.3.1. Windows

Общие ограничения циклов событий Windows:

Ограничения, специфичные для SelectorEventLoop:

Ограничения, специфичные для ProactorEventLoop:

Разрешение монотонного таймера в 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 не поддерживает символьные устройства в этих версиях. Для поддержки символьных устройств в этих версиях Mac OS X можно использовать SelectorEventLoop с SelectSelector или PollSelector. Пример:

python
import asyncio
import selectors

selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)

18.5.2.4. Политики цикла событий и политика по умолчанию

Управление циклом событий абстрагируется с помощью шаблона политика, чтобы обеспечить максимальную гибкость для собственных платформ и фреймворков. На протяжении выполнения процесса единственный глобальный объект политики управляет циклами событий, доступными процессу, в зависимости от контекста вызова. Политика – это объект, реализующий интерфейс AbstractEventLoopPolicy.

Для большинства пользователей asyncio с политиками никогда не приходится работать явно, поскольку глобальной политики по умолчанию достаточно (см. ниже).

Функции уровня модуля get_event_loop() и set_event_loop() предоставляют удобный доступ к циклам событий, управляемым политикой по умолчанию.

18.5.2.5. Интерфейс политики цикла событий

Политика цикла событий должна реализовывать следующий интерфейс:

classasyncio.AbstractEventLoopPolicy

Политика цикла событий.

get_event_loop()

Получает цикл событий для текущего контекста.

Возвращает объект цикла событий, реализующий интерфейс AbstractEventLoop. При вызове из корутины возвращает текущий выполняющийся цикл событий.

Возбуждает исключение, если для текущего контекста не был установлен цикл событий и текущая политика не предписывает его создать. Он никогда не должен возвращать None.

Изменено в версии 3.6.

set_event_loop(цикл)

Устанавливает цикл событий для текущего контекста в loop.

new_event_loop()

Создаёт и возвращает новый объект цикла событий в соответствии с правилами этой политики.

Если необходимо установить этот цикл как цикл событий для текущего контекста, set_event_loop() должен быть вызван явно.

Политика по умолчанию определяет контекст как текущий поток и управляет одним циклом событий на поток, который взаимодействует с asyncio. Если текущий поток ещё не имеет связанного с ним цикла событий, метод get_event_loop() политики по умолчанию создаёт его при вызове из главного потока, в противном случае возбуждает RuntimeError.

18.5.2.6. Доступ к глобальной политике цикла событий

asyncio.get_event_loop_policy()

Получает текущую политику цикла событий.

asyncio.set_event_loop_policy(политика)

Устанавливает текущую политику цикла событий. Если политика равно None, восстанавливается политика по умолчанию.

18.5.2.7. Настройка политики цикла событий

Для реализации новой политики цикла событий рекомендуется создать подкласс конкретной политики цикла событий по умолчанию DefaultEventLoopPolicy и переопределить методы, поведение которых нужно изменить, например:

python
class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):

    def get_event_loop(self):
        """Get the event loop.

        This may be None or an instance of EventLoop.
        """
        loop = super().get_event_loop()
        # Сделать что-то с loop ...
        return loop

asyncio.set_event_loop_policy(MyEventLoopPolicy())