asyncio-eventloops.md
1> **Источник:** https://python-all.ru/3.6/library/asyncio-eventloops.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 18.5.2. Циклы событий89**Исходный код:** [Lib/asyncio/events.py](https://python-all.ru/src/3.6/Lib/asyncio/events.py)1011## 18.5.2.1. Функции цикла событий1213Следующие функции представляют собой удобные сокращения для доступа к методам gлобальной политики. Обратите внимание, что это обеспечивает доступ к политике по умолчанию, если только альтернативная политика не была установлена вызовом [`set_event_loop_policy()`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.set_event_loop_policy) ранее в процессе выполнения программы.1415#### `asyncio.get_event_loop()`1617Эквивалентно вызову `get_event_loop_policy().get_event_loop()`.1819#### `asyncio.set_event_loop(loop)`2021Эквивалентно вызову `get_event_loop_policy().set_event_loop(loop)`.2223#### `asyncio.new_event_loop()`2425Эквивалентно вызову `get_event_loop_policy().new_event_loop()`.2627## 18.5.2.2. Доступные циклы событий2829asyncio в настоящее время предоставляет две реализации циклов событий: [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) и [`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop).3031#### `class asyncio.SelectorEventLoop`3233Цикл событий, основанный на модуле [`selectors`](https://python-all.ru/3.6/library/selectors.html#module-selectors). Подкласс [`AbstractEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop).3435Использует самый эффективный селектор, доступный на платформе.3637В Windows поддерживаются только сокеты (например, каналы не поддерживаются): см. [документацию MSDN по select](https://python-all.ru/3.6/library/asyncio-eventloops.html).3839#### `class asyncio.ProactorEventLoop`4041Proactor-цикл событий для Windows, использующий «I/O Completion Ports» (также известные как IOCP). Подкласс [`AbstractEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop).4243Доступность: Windows.4445> **См. также**46>47> [документация MSDN по портам завершения ввода-вывода](https://python-all.ru/3.6/library/asyncio-eventloops.html).4849Пример использования [`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) в Windows:5051```python52import asyncio, sys5354if sys.platform == 'win32':55 loop = asyncio.ProactorEventLoop()56 asyncio.set_event_loop(loop)57```5859## 18.5.2.3. Поддержка платформ6061Модуль [`asyncio`](https://python-all.ru/3.6/library/asyncio.html#module-asyncio) разработан как переносимый, но каждая платформа имеет свои тонкие различия и может не поддерживать все возможности [`asyncio`](https://python-all.ru/3.6/library/asyncio.html#module-asyncio).6263### 18.5.2.3.1. Windows6465Общие ограничения циклов событий Windows:6667- [`create_unix_connection()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_unix_connection) и [`create_unix_server()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_unix_server) не поддерживаются: семейство сокетов [`socket.AF_UNIX`](https://python-all.ru/3.6/library/socket.html#socket.AF_UNIX) специфично для UNIX68- [`add_signal_handler()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_signal_handler) и [`remove_signal_handler()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.remove_signal_handler) не поддерживаются69- `EventLoopPolicy.set_child_watcher()` не поддерживается. [`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) поддерживает подпроцессы. У него есть только одна реализация для наблюдения за дочерними процессами, настраивать её не нужно.7071[`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop)Специфические ограничения:7273- [`SelectSelector`](https://python-all.ru/3.6/library/selectors.html#selectors.SelectSelector) используется, он поддерживает только сокеты и ограничен 512 сокетами.74- [`add_reader()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_reader) и [`add_writer()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_writer) принимают только файловые дескрипторы сокетов75- Каналы не поддерживаются (например: [`connect_read_pipe()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.connect_read_pipe), [`connect_write_pipe()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.connect_write_pipe))76- [Подпроцессы](https://python-all.ru/3.6/library/asyncio-subprocess.html#asyncio-subprocess) не поддерживаются (например: [`subprocess_exec()`](https://python-all.ru/3.6/library/asyncio-subprocess.html#asyncio.AbstractEventLoop.subprocess_exec), [`subprocess_shell()`](https://python-all.ru/3.6/library/asyncio-subprocess.html#asyncio.AbstractEventLoop.subprocess_shell))7778[`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop)Специфические ограничения:7980- [`create_datagram_endpoint()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_datagram_endpoint) (UDP) не поддерживается.81- [`add_reader()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_reader) и [`add_writer()`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_writer) не поддерживаются.8283Разрешение монотонных часов в Windows обычно составляет около 15,6 мс. Наилучшее разрешение – 0,5 мс. Разрешение зависит от оборудования (наличие [HPET](https://python-all.ru/3.6/library/asyncio-eventloops.html)) и от конфигурации Windows. См. [отложенные вызовы asyncio](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio-delayed-calls).8485Изменено в версии 3.5: [`ProactorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) теперь поддерживает SSL.8687### 18.5.2.3.2. Mac OS X8889Символьные устройства, такие как PTY, хорошо поддерживаются только начиная с Mavericks (Mac OS 10.9). Они вообще не поддерживаются на Mac OS 10.5 и старше.9091На Mac OS 10.6, 10.7 и 10.8 цикл событий по умолчанию – это [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop), который использует [`selectors.KqueueSelector`](https://python-all.ru/3.6/library/selectors.html#selectors.KqueueSelector). [`selectors.KqueueSelector`](https://python-all.ru/3.6/library/selectors.html#selectors.KqueueSelector) не поддерживает символьные устройства на этих версиях. [`SelectorEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) можно использовать с [`SelectSelector`](https://python-all.ru/3.6/library/selectors.html#selectors.SelectSelector) или [`PollSelector`](https://python-all.ru/3.6/library/selectors.html#selectors.PollSelector) для поддержки символьных устройств на этих версиях Mac OS X. Пример:9293```python94import asyncio95import selectors9697selector = selectors.SelectSelector()98loop = asyncio.SelectorEventLoop(selector)99asyncio.set_event_loop(loop)100```101102## 18.5.2.4. Политики цикла событий и политика по умолчанию103104Управление циклом событий абстрагируется с помощью шаблона *политика*, чтобы обеспечить максимальную гибкость для нестандартных платформ и фреймворков. В ходе выполнения процесса единственный глобальный объект политики управляет циклами событий, доступными процессу, в зависимости от контекста вызова. Политика – это объект, реализующий интерфейс [`AbstractEventLoopPolicy`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.AbstractEventLoopPolicy).105106Для большинства пользователей [`asyncio`](https://python-all.ru/3.6/library/asyncio.html#module-asyncio) с политиками никогда не приходится явно иметь дело, поскольку глобальной политики по умолчанию достаточно (см. ниже).107108Функции уровня модуля [`get_event_loop()`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.get_event_loop) и [`set_event_loop()`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.set_event_loop) предоставляют удобный доступ к циклам событий, управляемым политикой по умолчанию.109110## 18.5.2.5. Интерфейс политики цикла событий111112Политика цикла событий должна реализовывать следующий интерфейс:113114#### `class asyncio.AbstractEventLoopPolicy`115116Политика цикла событий.117118#### `get_event_loop()`119120Возвращает цикл событий для текущего контекста.121122Возвращает объект цикла событий, реализующий интерфейс [`AbstractEventLoop`](https://python-all.ru/3.6/library/asyncio-eventloop.html#asyncio.AbstractEventLoop). При вызове из корутины возвращает текущий выполняющийся цикл событий.123124Вызывает исключение, если для текущего контекста не задан цикл событий и текущая политика не предписывает его создать. Он никогда не должен возвращать `None`.125126Изменено в версии 3.6.127128#### `set_event_loop(loop)`129130Устанавливает цикл событий для текущего контекста равным *loop*.131132#### `new_event_loop()`133134Создаёт и возвращает новый объект цикла событий в соответствии с правилами этой политики.135136Если необходимо установить этот цикл в качестве цикла событий для текущего контекста, [`set_event_loop()`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.set_event_loop) должен быть вызван явно.137138Политика по умолчанию определяет контекст как текущий поток и управляет циклом событий для каждого потока, который взаимодействует с [`asyncio`](https://python-all.ru/3.6/library/asyncio.html#module-asyncio). Если с текущим потоком ещё не связан цикл событий, метод [`get_event_loop()`](https://python-all.ru/3.6/library/asyncio-eventloops.html#asyncio.AbstractEventLoopPolicy.get_event_loop) политики по умолчанию создаёт его при вызове из главного потока, но в противном случае вызывает [`RuntimeError`](https://python-all.ru/3.6/library/exceptions.html#RuntimeError).139140## 18.5.2.6. Доступ к глобальной политике цикла событий141142#### `asyncio.get_event_loop_policy()`143144Возвращает текущую политику цикла событий.145146#### `asyncio.set_event_loop_policy(policy)`147148Устанавливает текущую политику цикла событий. Если *политика* равна `None`, восстанавливается политика по умолчанию.149150## 18.5.2.7. Настройка политики цикла событий151152Чтобы реализовать новую политику цикла событий, рекомендуется создать подкласс конкретной политики цикла событий по умолчанию `DefaultEventLoopPolicy` и переопределить методы, поведение которых требуется изменить, например:153154```python155class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):156157 def get_event_loop(self):158 """Получить цикл событий.159160 Это может быть None или экземпляр EventLoop.161 """162 loop = super().get_event_loop()163 # Сделать что-то с циклом ...164 return loop165166asyncio.set_event_loop_policy(MyEventLoopPolicy())167```168