asyncio-eventloop.md · Markdown – Документация Python
Документация Python неофициальный перевод

asyncio-eventloop.md

643 строк · 56.6 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.4/library/asyncio-eventloop.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# 18.5.1. Базовый цикл событий89Цикл событий – центральное исполнительное устройство, предоставляемое [`asyncio`](https://python-all.ru/3.4/library/asyncio.html#module-asyncio). Он предоставляет множество возможностей, в том числе:1011- Регистрация, выполнение и отмена отложенных вызовов (тайм-аутов).12- Создание [*транспортов*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-transport) клиента и сервера для различных видов взаимодействия.13- Запуск подпроцессов и связанных с ними [*транспортов*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-transport) для взаимодействия с внешней программой.14- Делегирование дорогостоящих вызовов функций пулу потоков.1516#### `class asyncio.BaseEventLoop`1718Базовый класс циклов событий.1920This class is [*не является потокобезопасным*](https://python-all.ru/3.4/library/asyncio-dev.html#asyncio-multithreading).2122## 18.5.1.1. Запуск цикла событий2324#### `BaseEventLoop.run_forever()`2526Выполняется до тех пор, пока не будет вызван [`stop()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.stop). Если [`stop()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.stop) вызывается до вызова [`run_forever()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.run_forever), то производится однократный опрос селектора ввода/вывода с нулевым тайм-аутом, выполняются все колбэки, запланированные в ответ на события ввода/вывода (а также те, что уже были запланированы), после чего происходит выход. Если [`stop()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.stop) вызывается во время выполнения [`run_forever()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.run_forever), то будут выполнены текущие колбэки, после чего произойдёт выход. Обратите внимание, что колбэки, запланированные другими колбэками, в этом случае выполнены не будут; они выполнятся при следующем вызове [`run_forever()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.run_forever).2728Изменено в версии 3.4.4.2930#### `BaseEventLoop.run_until_complete(future)`3132Выполняется до завершения [`Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future).3334Если аргумент является [*объектом корутины*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine), то он оборачивается с помощью [`async()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.async).3536Возвращает результат Future или возбуждает его исключение.3738#### `BaseEventLoop.is_running()`3940Возвращает статус выполнения цикла событий.4142#### `BaseEventLoop.stop()`4344Останавливает выполнение цикла событий.4546Это приводит к выходу из [`run_forever()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.run_forever) при первой же подходящей возможности (см. описание выше для получения подробностей).4748Изменено в версии 3.4.4.4950#### `BaseEventLoop.is_closed()`5152Возвращает `True`, если цикл событий был закрыт.5354Новое в версии 3.4.2.5556#### `BaseEventLoop.close()`5758Закрывает цикл событий. Цикл не должен выполняться. Ожидающие колбэки будут потеряны.5960Это очищает очереди и завершает работу исполнителя, но не дожидается его полной остановки.6162Это идемпотентно и необратимо. После этого метода не следует вызывать никакие другие методы.6364## 18.5.1.2. Вызовы6566Большинство функций [`asyncio`](https://python-all.ru/3.4/library/asyncio.html#module-asyncio) не принимают именованные аргументы. Если нужно передать именованные аргументы в колбэк, используйте [`functools.partial()`](https://python-all.ru/3.4/library/functools.html#functools.partial). Например, `loop.call_soon(functools.partial(print, "Hello", flush=True))` вызовет `print("Hello", flush=True)`.6768> **Примечание**69>70> [`functools.partial()`](https://python-all.ru/3.4/library/functools.html#functools.partial) предпочтительнее `lambda`-функций, поскольку [`asyncio`](https://python-all.ru/3.4/library/asyncio.html#module-asyncio) может анализировать объект [`functools.partial()`](https://python-all.ru/3.4/library/functools.html#functools.partial) для отображения параметров в режиме отладки, в то время как `lambda`-функции имеют слабое представление.7172#### `BaseEventLoop.call_soon(callback, *args)`7374Планирует вызов колбэка как можно скорее. Колбэк вызывается после возврата из [`call_soon()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_soon), когда управление возвращается в цикл событий.7576Это работает как очередь FIFO: колбэки вызываются в порядке, в котором они зарегистрированы. Каждый колбэк вызывается ровно один раз.7778Любые позиционные аргументы, указанные после колбэка, будут переданы ему при вызове.7980Возвращается экземпляр [`asyncio.Handle`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.8182[*Используйте functools.partial для передачи именованных аргументов в колбэк*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-pass-keywords).8384#### `BaseEventLoop.call_soon_threadsafe(callback, *args)`8586Аналог [`call_soon()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_soon), но потокобезопасный.8788См. раздел [*concurrency and multithreading*](https://python-all.ru/3.4/library/asyncio-dev.html#asyncio-multithreading) документации.8990## 18.5.1.3. Отложенные вызовы9192Цикл событий имеет собственные внутренние часы для вычисления тайм-аутов. Какие именно часы используются, зависит от (зависящей от платформы) реализации цикла событий; в идеале это монотонные часы. Обычно это другие часы, отличные от [`time.time()`](https://python-all.ru/3.4/library/time.html#time.time).9394> **Примечание**95>96> Тайм-ауты (относительная *задержка* или абсолютное *время*) не должны превышать одних суток.9798#### `BaseEventLoop.call_later(delay, callback, *args)`99100Организует вызов *колбэка* через заданную *задержку* в секундах (целое число или float).101102Возвращается экземпляр [`asyncio.Handle`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.103104*колбэк* будет вызван ровно один раз при каждом вызове [`call_later()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_later). Если два колбэка запланированы на одно и то же время, порядок их вызова не определён.105106Необязательные позиционные *args* будут переданы колбэку при его вызове. Если нужно, чтобы колбэк вызывался с некоторыми именованными аргументами, используйте замыкание или [`functools.partial()`](https://python-all.ru/3.4/library/functools.html#functools.partial).107108[*Используйте functools.partial для передачи именованных аргументов в колбэк*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-pass-keywords).109110#### `BaseEventLoop.call_at(when, callback, *args)`111112Планирует вызов *колбэк* в заданную абсолютную временную метку *when* (целое число или число с плавающей запятой), используя ту же привязку ко времени, что и [`BaseEventLoop.time()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.time).113114Поведение этого метода такое же, как у [`call_later()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_later).115116Возвращается экземпляр [`asyncio.Handle`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.117118[*Используйте functools.partial для передачи именованных аргументов в колбэк*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-pass-keywords).119120#### `BaseEventLoop.time()`121122Возвращает текущее время в виде значения [`float`](https://python-all.ru/3.4/library/functions.html#float) в соответствии с внутренними часами цикла событий.123124> **См. также**125>126> Функция [`asyncio.sleep()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.sleep).127128## 18.5.1.4. Задачи129130#### `BaseEventLoop.create_task(coro)`131132Планирует выполнение [*объекта корутины*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine): оборачивает его в future. Возвращает объект [`задача`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Task).133134Сторонние циклы событий могут использовать собственный подкласс [`задача`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Task) для совместимости. В этом случае тип результата является подклассом [`задача`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Task).135136Этот метод был добавлен в Python 3.4.2. Используйте функцию [`async()`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.async), чтобы поддерживать также старые версии Python.137138Новое в версии 3.4.2.139140#### `BaseEventLoop.set_task_factory(factory)`141142Устанавливает фабрику задач, которая будет использоваться [`BaseEventLoop.create_task()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_task).143144Если *factory* равен `None`, будет установлена фабрика задач по умолчанию.145146Если *factory* является *вызываемым объектом*, его сигнатура должна соответствовать `(loop, coro)`, где *loop* будет ссылкой на активный цикл событий, а *coro* – объектом корутины. Вызываемый объект должен возвращать совместимый объект [`asyncio.Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future).147148Новое в версии 3.4.4.149150#### `BaseEventLoop.get_task_factory()`151152Возвращает фабрику задач или `None`, если используется стандартная.153154Новое в версии 3.4.4.155156## 18.5.1.5. Создание соединений157158#### `coroutine BaseEventLoop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None)`159160Создает потоковое транспортное соединение с указанными *узлом* и *портом*: семейство сокетов [`AF_INET`](https://python-all.ru/3.4/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.4/library/socket.html#socket.AF_INET6) в зависимости от *узла* (или *family*, если задано), тип сокета [`SOCK_STREAM`](https://python-all.ru/3.4/library/socket.html#socket.SOCK_STREAM). *protocol\_factory* должна быть вызываемым объектом, возвращающим экземпляр [*протокола*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-protocol).161162Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine), которая будет пытаться установить соединение в фоновом режиме. В случае успеха корутина возвращает пару `(транспорт, протокол)`.163164Хронологическая последовательность выполняемой операции следующая:1651661. Соединение установлено, и создаётся [*транспорт*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-transport), представляющий его.1672. *protocol\_factory* вызывается без аргументов и должен возвращать экземпляр [*протокола*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-protocol).1683. Экземпляр протокола привязан к транспорту, и вызывается его метод `connection_made()`.1694. Корутина успешно завершается, возвращая пару `(транспорт, протокол)`.170171Созданный транспорт является двунаправленным потоком, зависящим от реализации.172173> **Примечание**174>175> *protocol\_factory* может быть вызываемым объектом любого вида, не обязательно классом. Например, для использования предварительно созданного экземпляра протокола можно передать `lambda: my_protocol`.176177Параметры, позволяющие изменить способ создания соединения:178179- *ssl*: если задан и не равен false, создается SSL/TLS транспорт (по умолчанию создается обычный TCP транспорт). Если *ssl* является объектом [`ssl.SSLContext`](https://python-all.ru/3.4/library/ssl.html#ssl.SSLContext), этот контекст используется для создания транспорта; если *ssl* равен [`True`](https://python-all.ru/3.4/library/constants.html#True), используется контекст с некоторыми неопределенными настройками по умолчанию.180181  > **См. также**182  >183  > [*Вопросы безопасности SSL/TLS*](https://python-all.ru/3.4/library/ssl.html#ssl-security)184- *server\_hostname* используется только вместе с *ssl* и задаёт или переопределяет имя хоста, с которым будет сравниваться сертификат целевого сервера. По умолчанию используется значение аргумента *host*. Если *host* пуст, значение по умолчанию отсутствует, и необходимо передать значение для *server\_hostname*. Если *server\_hostname* является пустой строкой, проверка имени хоста отключается (что представляет серьёзную угрозу безопасности, допуская атаки man-in-the-middle).185- *family*, *proto*, *flags* – необязательные семейство адреса, протокол и флаги, передаваемые в getaddrinfo() для разрешения *узла*. Если заданы, все они должны быть целыми числами из соответствующих констант модуля [`socket`](https://python-all.ru/3.4/library/socket.html#module-socket).186- *sock*, если задан, должен быть существующим, уже подключенным объектом [`socket.socket`](https://python-all.ru/3.4/library/socket.html#socket.socket), который будет использоваться транспортом. Если *sock* задан, не нужно указывать *host*, *port*, *family*, *proto*, *flags* и *local\_addr*.187- *local\_addr*, если задан, представляет собой кортеж `(local_host, local_port)`, используемый для локальной привязки сокета. *local\_host* и *local\_port* разрешаются с помощью getaddrinfo(), аналогично *host* и *port*.188189В Windows с [`ProactorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) SSL/TLS не поддерживается.190191> **См. также**192>193> Функция [`open_connection()`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.open_connection) может использоваться для получения пары ([`StreamReader`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.StreamReader), [`StreamWriter`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.StreamWriter)) вместо протокола.194195#### `coroutine BaseEventLoop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_address=None, reuse_port=None, allow_broadcast=None, sock=None)`196197Создание датаграмного соединения: семейство сокетов [`AF_INET`](https://python-all.ru/3.4/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.4/library/socket.html#socket.AF_INET6) в зависимости от *узла* (или *family*, если задано), тип сокета [`SOCK_DGRAM`](https://python-all.ru/3.4/library/socket.html#socket.SOCK_DGRAM). *protocol\_factory* должна быть вызываемым объектом, возвращающим экземпляр [*протокола*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-protocol).198199Этот метод представляет собой [*корутину*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine), которая пытается установить соединение в фоновом режиме. В случае успеха корутина возвращает пару `(транспорт, протокол)`.200201Параметры, изменяющие способ создания соединения:202203- Параметр *local\_addr*, если указан, представляет собой кортеж `(local_host, local_port)`, используемый для локальной привязки сокета. Значения *local\_host* и *local\_port* определяются с помощью [`getaddrinfo()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.getaddrinfo).204- Параметр *remote\_addr*, если указан, представляет собой кортеж `(remote_host, remote_port)`, используемый для подключения сокета к удалённому адресу. Значения *remote\_host* и *remote\_port* определяются с помощью [`getaddrinfo()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.getaddrinfo).205- Параметры *family*, *proto*, *flags* – это необязательные семейство адресов, протокол и флаги, которые передаются в [`getaddrinfo()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.getaddrinfo) для разрешения *host*. Если указаны, все они должны быть целыми числами из соответствующих констант модуля [`socket`](https://python-all.ru/3.4/library/socket.html#module-socket).206- Параметр *reuse\_address* указывает ядру повторно использовать локальный сокет в состоянии TIME\_WAIT, не дожидаясь истечения его естественного таймаута. Если не указан, автоматически устанавливается в True на UNIX.207- Параметр *reuse\_port* указывает ядру разрешить привязку этой конечной точки к тому же порту, к которому привязаны другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Эта опция не поддерживается в Windows и некоторых UNIX. Если константа `SO_REUSEPORT` не определена, то эта возможность не поддерживается.208- *allow\_broadcast* указывает ядру разрешить этой конечной точке отправлять сообщения на широковещательный адрес.209- Параметр *sock* может быть указан для использования ранее созданного, уже подключённого объекта [`socket.socket`](https://python-all.ru/3.4/library/socket.html#socket.socket), который будет использоваться транспортом. Если он указан, *local\_addr* и *remote\_addr* должны быть опущены (должны быть [`None`](https://python-all.ru/3.4/library/constants.html#None)).210211В Windows с [`ProactorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) этот метод не поддерживается.212213См. примеры [*протокол UDP-клиента эхо*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-udp-echo-client-protocol) и [*протокол UDP-сервера эхо*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-udp-echo-server-protocol).214215#### `coroutine BaseEventLoop.create_unix_connection(protocol_factory, path, *, ssl=None, sock=None, server_hostname=None)`216217Создание UNIX-соединения: семейство сокетов [`AF_UNIX`](https://python-all.ru/3.4/library/socket.html#socket.AF_UNIX), тип сокета [`SOCK_STREAM`](https://python-all.ru/3.4/library/socket.html#socket.SOCK_STREAM). Семейство сокетов [`AF_UNIX`](https://python-all.ru/3.4/library/socket.html#socket.AF_UNIX) используется для эффективного обмена данными между процессами на одной машине.218219Этот метод представляет собой [*корутину*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine), которая пытается установить соединение в фоновом режиме. В случае успеха корутина возвращает пару `(транспорт, протокол)`.220221Смотрите метод [`BaseEventLoop.create_connection()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_connection) для получения информации о параметрах.222223Доступность: UNIX.224225## 18.5.1.6. Создание принимающих соединений226227#### `coroutine BaseEventLoop.create_server(protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None)`228229Создаёт TCP-сервер (тип сокета [`SOCK_STREAM`](https://python-all.ru/3.4/library/socket.html#socket.SOCK_STREAM)), привязанный к *host* и *port*.230231Возвращает объект [`Server`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Server), его атрибут [`sockets`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Server.sockets) содержит созданные сокеты. Используйте метод [`Server.close()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Server.close) для остановки сервера: закрывает принимающие сокеты.232233Параметры:234235- Параметр *host* может быть строкой; в этом случае TCP-сервер привязывается к *host* и *port*. Параметр *host* также может быть последовательностью строк; в этом случае TCP-сервер привязывается ко всем хостам из этой последовательности. Если *host* является пустой строкой или `None`, предполагаются все интерфейсы и будет возвращён список из нескольких сокетов (скорее всего, один для IPv4 и один для IPv6).236- Параметр *family* может быть установлен в [`socket.AF_INET`](https://python-all.ru/3.4/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.4/library/socket.html#socket.AF_INET6), чтобы принудительно использовать IPv4 или IPv6. Если не задан, он будет определён из host (по умолчанию `socket.AF_UNSPEC`).237- Параметр *flags* – это битовая маска для [`getaddrinfo()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.getaddrinfo).238- Параметр *sock* может быть указан для использования ранее созданного объекта сокета. Если он указан, *host* и *port* должны быть опущены (должны быть [`None`](https://python-all.ru/3.4/library/constants.html#None)).239- Параметр *backlog* – это максимальное количество ожидающих соединений, передаваемое в [`listen()`](https://python-all.ru/3.4/library/socket.html#socket.socket.listen) (по умолчанию 100).240- Параметр *ssl* может быть установлен в [`SSLContext`](https://python-all.ru/3.4/library/ssl.html#ssl.SSLContext) для включения SSL при принимаемых соединениях.241- Параметр *reuse\_address* указывает ядру повторно использовать локальный сокет в состоянии TIME\_WAIT, не дожидаясь истечения его естественного таймаута. Если не указан, автоматически устанавливается в True на UNIX.242- *reuse\_port* указывает ядру разрешить привязку этой конечной точки к тому же порту, к которому привязаны другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Эта опция не поддерживается в Windows.243244Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).245246В Windows с [`ProactorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) SSL/TLS не поддерживается.247248> **См. также**249>250> Функция [`start_server()`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.start_server) создаёт пару [`StreamReader`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.StreamReader), [`StreamWriter`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.StreamWriter) и вызывает колбэк-функцию с этой парой.251252Изменено в версии 3.4.4: Параметр *host* теперь может быть последовательностью строк.253254#### `coroutine BaseEventLoop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None)`255256Аналогично [`BaseEventLoop.create_server()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_server), но для семейства сокетов [`AF_UNIX`](https://python-all.ru/3.4/library/socket.html#socket.AF_UNIX).257258Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).259260Доступность: UNIX.261262## 18.5.1.7. Отслеживание файловых дескрипторов263264В Windows с [`SelectorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) поддерживаются только дескрипторы сокетов (например, файловые дескрипторы каналов не поддерживаются).265266В Windows с [`ProactorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) эти методы не поддерживаются.267268#### `BaseEventLoop.add_reader(fd, callback, *args)`269270Начать наблюдение за файловым дескриптором на готовность к чтению и затем вызвать *колбэк* с указанными аргументами.271272[*Используйте functools.partial для передачи именованных аргументов в колбэк*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-pass-keywords).273274#### `BaseEventLoop.remove_reader(fd)`275276Прекратить наблюдение за файловым дескриптором на готовность к чтению.277278#### `BaseEventLoop.add_writer(fd, callback, *args)`279280Начать наблюдение за файловым дескриптором на готовность к записи и затем вызвать *колбэк* с указанными аргументами.281282[*Используйте functools.partial для передачи именованных аргументов в колбэк*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-pass-keywords).283284#### `BaseEventLoop.remove_writer(fd)`285286Прекратить наблюдение за файловым дескриптором на готовность к записи.287288Пример [*наблюдения за файловым дескриптором на события чтения*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-watch-read-event) использует низкоуровневый метод [`BaseEventLoop.add_reader()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.add_reader) для регистрации файлового дескриптора сокета.289290## 18.5.1.8. Низкоуровневые операции с сокетами291292#### `coroutine BaseEventLoop.sock_recv(sock, nbytes)`293294Получает данные из сокета. Возвращаемое значение – объект типа bytes, представляющий полученные данные. Максимальный объём данных, получаемых за один раз, задаётся параметром *nbytes*.295296В цикле событий [`SelectorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) сокет *sock* должен быть неблокирующим.297298Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).299300> **См. также**301>302> Метод [`socket.socket.recv()`](https://python-all.ru/3.4/library/socket.html#socket.socket.recv).303304#### `coroutine BaseEventLoop.sock_sendall(sock, data)`305306Отправляет данные в сокет. Сокет должен быть подключён к удалённому сокету. Этот метод продолжает отправку данных из *data*, пока не будут отправлены все данные или не возникнет ошибка. При успешном завершении возвращается `None`. В случае ошибки возникает исключение, и невозможно определить, какая часть данных (если вообще какая-либо) была успешно обработана принимающей стороной соединения.307308В цикле событий [`SelectorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) сокет *sock* должен быть неблокирующим.309310Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).311312> **См. также**313>314> Метод [`socket.socket.sendall()`](https://python-all.ru/3.4/library/socket.html#socket.socket.sendall).315316#### `coroutine BaseEventLoop.sock_connect(sock, address)`317318Подключается к удалённому сокету по адресу *address*.319320Адрес *address* должен быть предварительно разрешён, чтобы избежать ситуации, когда весь цикл событий зависает из-за необходимости выполнения DNS-запроса для этого адреса. Например, это должен быть IP-адрес, а не имя хоста, для семейств адресов [`AF_INET`](https://python-all.ru/3.4/library/socket.html#socket.AF_INET) и [`AF_INET6`](https://python-all.ru/3.4/library/socket.html#socket.AF_INET6). Используйте [`getaddrinfo()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.getaddrinfo) для асинхронного разрешения имени хоста.321322В цикле событий [`SelectorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) сокет *sock* должен быть неблокирующим.323324Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).325326> **См. также**327>328> Метод [`BaseEventLoop.create_connection()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_connection), функция [`open_connection()`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.open_connection) и метод [`socket.socket.connect()`](https://python-all.ru/3.4/library/socket.html#socket.socket.connect).329330#### `coroutine BaseEventLoop.sock_accept(sock)`331332Принимает соединение. Сокет должен быть привязан к адресу и ожидать подключений. Возвращаемое значение – пара `(conn, address)`, где *conn* – это *новый* объект сокета, который можно использовать для отправки и получения данных по соединению, а *address* – это адрес, привязанный к сокету на другом конце соединения.333334Сокет *sock* должен быть неблокирующим.335336Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).337338> **См. также**339>340> Метод [`BaseEventLoop.create_server()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_server), функция [`start_server()`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.start_server) и метод [`socket.socket.accept()`](https://python-all.ru/3.4/library/socket.html#socket.socket.accept).341342## 18.5.1.9. Разрешение имени хоста343344#### `coroutine BaseEventLoop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0)`345346Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine), аналогичной функции [`socket.getaddrinfo()`](https://python-all.ru/3.4/library/socket.html#socket.getaddrinfo), но неблокирующей.347348#### `coroutine BaseEventLoop.getnameinfo(sockaddr, flags=0)`349350Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine), аналогичной функции [`socket.getnameinfo()`](https://python-all.ru/3.4/library/socket.html#socket.getnameinfo), но неблокирующей.351352## 18.5.1.10. Подключение каналов353354В Windows с циклом событий [`SelectorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) эти методы не поддерживаются. Используйте [`ProactorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) для поддержки каналов в Windows.355356#### `coroutine BaseEventLoop.connect_read_pipe(protocol_factory, pipe)`357358Регистрирует канал чтения в цикле событий.359360*protocol\_factory* должен создавать объект с интерфейсом [`Protocol`](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio.Protocol). *pipe* – это [*файлоподобный объект*](https://python-all.ru/3.4/glossary.html#term-file-object). Возвращает пару `(транспорт, протокол)`, где *транспорт* поддерживает интерфейс [`ReadTransport`](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio.ReadTransport).361362В цикле событий [`SelectorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) канал *pipe* переводится в неблокирующий режим.363364Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).365366#### `coroutine BaseEventLoop.connect_write_pipe(protocol_factory, pipe)`367368Регистрирует канал записи в цикле событий.369370*protocol\_factory* должен создавать объект с `BaseProtocol` интерфейсом. *pipe* – это [*файлоподобный объект*](https://python-all.ru/3.4/glossary.html#term-file-object). Возвращает пару `(транспорт, протокол)`, где *транспорт* поддерживает интерфейс [`WriteTransport`](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio.WriteTransport).371372С циклом событий [`SelectorEventLoop`](https://python-all.ru/3.4/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) *pipe* устанавливается в неблокирующий режим.373374Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).375376> **См. также**377>378> Методы [`BaseEventLoop.subprocess_exec()`](https://python-all.ru/3.4/library/asyncio-subprocess.html#asyncio.BaseEventLoop.subprocess_exec) и [`BaseEventLoop.subprocess_shell()`](https://python-all.ru/3.4/library/asyncio-subprocess.html#asyncio.BaseEventLoop.subprocess_shell).379380## 18.5.1.11. Сигналы UNIX381382Доступно: только UNIX.383384#### `BaseEventLoop.add_signal_handler(signum, callback, *args)`385386Добавляет обработчик сигнала.387388Возбуждает [`ValueError`](https://python-all.ru/3.4/library/exceptions.html#ValueError), если номер сигнала недействителен или не может быть перехвачен. Возбуждает [`RuntimeError`](https://python-all.ru/3.4/library/exceptions.html#RuntimeError), если возникла проблема при настройке обработчика.389390[*Используйте functools.partial для передачи именованных аргументов в колбэк*](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-pass-keywords).391392#### `BaseEventLoop.remove_signal_handler(sig)`393394Удаляет обработчик сигнала.395396Возвращает `True`, если обработчик сигнала был удалён, `False` в противном случае.397398> **См. также**399>400> Модуль [`signal`](https://python-all.ru/3.4/library/signal.html#module-signal).401402## 18.5.1.12. Исполнитель403404[`Executor`](https://python-all.ru/3.4/library/concurrent.futures.html#concurrent.futures.Executor) (пул потоков или пул процессов). По умолчанию цикл событий использует исполнитель на пуле потоков ([`ThreadPoolExecutor`](https://python-all.ru/3.4/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)).405406#### `coroutine BaseEventLoop.run_in_executor(executor, func, *args)`407408Планирует вызов функции *func* в указанном исполнителе.409410Аргумент *executor* должен быть экземпляром [`Executor`](https://python-all.ru/3.4/library/concurrent.futures.html#concurrent.futures.Executor) . Исполнитель по умолчанию используется, если *executor* равен `None`.411412[*Используйте functools.partial для передачи именованных аргументов в \*func\**](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio-pass-keywords).413414Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).415416#### `BaseEventLoop.set_default_executor(executor)`417418Устанавливает исполнитель по умолчанию, используемый [`run_in_executor()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.run_in_executor).419420## 18.5.1.13. API обработки ошибок421422Позволяет настроить обработку исключений в цикле событий.423424#### `BaseEventLoop.set_exception_handler(handler)`425426Устанавливает *handler* в качестве нового обработчика исключений цикла событий.427428Если *handler* равен `None`, обработчик исключений по умолчанию будет установлен.429430Если *handler* является вызываемым объектом, его сигнатура должна соответствовать `(loop, context)`, где `loop` будет ссылкой на активный цикл событий, `context` будет объектом `dict` (см. документацию [`call_exception_handler()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_exception_handler) для подробностей о context).431432#### `BaseEventLoop.default_exception_handler(context)`433434Обработчик исключений по умолчанию.435436Вызывается при возникновении исключения, когда не установлен обработчик исключений, а также может вызываться пользовательским обработчиком исключений, который хочет передать управление стандартному поведению.437438Параметр *context* имеет то же значение, что и в [`call_exception_handler()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_exception_handler).439440#### `BaseEventLoop.call_exception_handler(context)`441442Вызывает обработчик исключений текущего цикла событий.443444*context* – это объект `dict`, содержащий следующие ключи (новые ключи могут быть добавлены позже):445446- ‘message’: сообщение об ошибке;447- 'исключение' (необязательно): объект исключения;448- ‘future’ (необязательно): экземпляр [`asyncio.Future`](https://python-all.ru/3.4/library/asyncio-task.html#asyncio.Future);449- ‘handle’ (необязательно): экземпляр [`asyncio.Handle`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Handle);450- 'протокол' (необязательно): экземпляр [*Protocol*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-protocol);451- 'транспорт' (необязательно): экземпляр [*Transport*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-transport);452- ‘socket’ (необязательно): экземпляр [`socket.socket`](https://python-all.ru/3.4/library/socket.html#socket.socket).453454> **Примечание**455>456> Примечание: этот метод не следует переопределять в подклассах циклов событий. Для любой пользовательской обработки исключений используйте метод [`set_exception_handler()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.set_exception_handler).457458## 18.5.1.14. Режим отладки459460#### `BaseEventLoop.get_debug()`461462Возвращает режим отладки ([`bool`](https://python-all.ru/3.4/library/functions.html#bool)) цикла событий.463464Значение по умолчанию – `True`, если переменная окружения [`PYTHONASYNCIODEBUG`](https://python-all.ru/3.4/using/cmdline.html#envvar-PYTHONASYNCIODEBUG) установлена в непустую строку, и `False` в противном случае.465466Новое в версии 3.4.2.467468#### `BaseEventLoop.set_debug(enabled: bool)`469470Устанавливает режим отладки цикла событий.471472Новое в версии 3.4.2.473474> **См. также**475>476> [*Режим отладки asyncio*](https://python-all.ru/3.4/library/asyncio-dev.html#asyncio-debug-mode).477478## 18.5.1.15. Server479480#### `class asyncio.Server`481482Сервер, прослушивающий сокеты.483484Объект создаётся методом [`BaseEventLoop.create_server()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_server) и функцией [`start_server()`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.start_server). Не создавайте экземпляр класса напрямую.485486#### `close()`487488Прекратить обслуживание: закрыть прослушивающие сокеты и установить атрибут [`sockets`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Server.sockets) в значение `None`.489490Сокеты, соответствующие уже установленным входящим клиентским подключениям, остаются открытыми.491492Сервер закрывается асинхронно, используйте корутину [`wait_closed()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Server.wait_closed) для ожидания закрытия сервера.493494#### `coroutine wait_closed()`495496Дождаться завершения метода [`close()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.Server.close).497498Этот метод является [*корутиной*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).499500#### `sockets`501502Список объектов [`socket.socket`](https://python-all.ru/3.4/library/socket.html#socket.socket), которые прослушивает сервер, или `None`, если сервер закрыт.503504## 18.5.1.16. Handle505506#### `class asyncio.Handle`507508Объект-обёртка колбэка, возвращаемый методами [`BaseEventLoop.call_soon()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_soon), [`BaseEventLoop.call_soon_threadsafe()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_soon_threadsafe), [`BaseEventLoop.call_later()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_later), и [`BaseEventLoop.call_at()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_at).509510#### `cancel()`511512Отменяет вызов. Если колбэк уже отменён или выполнен, этот метод ничего не делает.513514## 18.5.1.17. Примеры использования цикла событий515516### 18.5.1.17.1. Hello World с использованием call\_soon()517518Пример использования метода [`BaseEventLoop.call_soon()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_soon) для планирования колбэка. Колбэк выводит на экран `"Hello World"` и затем останавливает цикл событий:519520```python521import asyncio522523def hello_world(loop):524    print('Hello World')525    loop.stop()526527loop = asyncio.get_event_loop()528529# Запланировать вызов hello_world()530loop.call_soon(hello_world, loop)531532# Блокирующий вызов прерван loop.stop()533loop.run_forever()534loop.close()535```536537> **См. также**538>539> Пример [*корутины Hello World*](https://python-all.ru/3.4/library/asyncio-task.html#asyncio-hello-world-coroutine) использует [*корутину*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).540541### 18.5.1.17.2. Отображение текущей даты с помощью call\_later()542543Пример колбэка, который каждую секунду выводит текущую дату. Колбэк использует метод [`BaseEventLoop.call_later()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.call_later), чтобы перепланировать себя в течение 5 секунд, а затем останавливает цикл событий:544545```python546import asyncio547import datetime548549def display_date(end_time, loop):550    print(datetime.datetime.now())551    if (loop.time() + 1.0) < end_time:552        loop.call_later(1, display_date, end_time, loop)553    else:554        loop.stop()555556loop = asyncio.get_event_loop()557558# Запланировать первый вызов display_date()559end_time = loop.time() + 5.0560loop.call_soon(display_date, end_time, loop)561562# Блокирующий вызов прерван loop.stop()563loop.run_forever()564loop.close()565```566567> **См. также**568>569> Пример [*корутины, отображающей текущую дату*](https://python-all.ru/3.4/library/asyncio-task.html#asyncio-date-coroutine) использует [*корутину*](https://python-all.ru/3.4/library/asyncio-task.html#coroutine).570571### 18.5.1.17.3. Отслеживание событий чтения файлового дескриптора572573Ожидать, пока файловый дескриптор не получит некоторые данные, используя метод [`BaseEventLoop.add_reader()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.add_reader), а затем закрыть цикл событий:574575```python576import asyncio577try:578    from socket import socketpair579except ImportError:580    from asyncio.windows_utils import socketpair581582# Создать пару связанных файловых дескрипторов583rsock, wsock = socketpair()584loop = asyncio.get_event_loop()585586def reader():587    data = rsock.recv(100)588    print("Received:", data.decode())589    # Готово: отменить регистрацию файлового дескриптора590    loop.remove_reader(rsock)591    # Остановить цикл событий592    loop.stop()593594# Зарегистрировать файловый дескриптор для события чтения595loop.add_reader(rsock, reader)596597# Симулировать приём данных из сети598loop.call_soon(wsock.send, 'abc'.encode())599600# Запустить цикл событий601loop.run_forever()602603# Готово, закрыть сокеты и цикл событий.604rsock.close()605wsock.close()606loop.close()607```608609> **См. также**610>611> Пример [*регистрация открытого сокета для ожидания данных с использованием протокола*](https://python-all.ru/3.4/library/asyncio-protocol.html#asyncio-register-socket) использует низкоуровневый протокол, создаваемый методом [`BaseEventLoop.create_connection()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.create_connection).612>613> Пример [*регистрация открытого сокета для ожидания данных с использованием потоков данных*](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio-register-socket-streams) использует высокоуровневые потоки данных, создаваемые функцией [`open_connection()`](https://python-all.ru/3.4/library/asyncio-stream.html#asyncio.open_connection) в корутине.614615### 18.5.1.17.4. Установка обработчиков сигналов SIGINT и SIGTERM616617Зарегистрировать обработчики для сигналов `SIGINT` и `SIGTERM`, используя метод [`BaseEventLoop.add_signal_handler()`](https://python-all.ru/3.4/library/asyncio-eventloop.html#asyncio.BaseEventLoop.add_signal_handler):618619```python620import asyncio621import functools622import os623import signal624625def ask_exit(signame):626    print("got signal %s: exit" % signame)627    loop.stop()628629loop = asyncio.get_event_loop()630for signame in ('SIGINT', 'SIGTERM'):631    loop.add_signal_handler(getattr(signal, signame),632                            functools.partial(ask_exit, signame))633634print("Event loop running forever, press Ctrl+C to interrupt.")635print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid())636try:637    loop.run_forever()638finally:639    loop.close()640```641642Этот пример работает только на UNIX.643