Документация Python неофициальный перевод

asyncio-eventloop.md

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

1> **Источник:** https://python-all.ru/3.5/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.5/library/asyncio.html#module-asyncio). Он предоставляет множество возможностей, в том числе:1011- Регистрация, выполнение и отмена отложенных вызовов (тайм-аутов).12- Создание [транспортов](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-transport) клиента и сервера для различных видов взаимодействия.13- Запуск подпроцессов и связанных с ними [транспортов](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-transport) для взаимодействия с внешней программой.14- Делегирование дорогостоящих вызовов функций пулу потоков.1516#### `class asyncio.BaseEventLoop`1718Этот класс является деталью реализации. Он является подклассом [`AbstractEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop) и может быть базовым классом конкретных реализаций цикла событий, находящихся в [`asyncio`](https://python-all.ru/3.5/library/asyncio.html#module-asyncio). Его не следует использовать напрямую; вместо этого используйте [`AbstractEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop). `BaseEventLoop` не должен наследоваться сторонним кодом; внутренний интерфейс нестабилен.1920#### `class asyncio.AbstractEventLoop`2122Абстрактный базовый класс циклов событий.2324This class is [не является потокобезопасным](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-multithreading).2526## 18.5.1.1. Запуск цикла событий2728#### `AbstractEventLoop.run_forever()`2930Выполняется до вызова [`stop()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.stop). Если [`stop()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.stop) вызывается до вызова [`run_forever()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_forever), то однократно опрашивается I/O-селектор с нулевым тайм-аутом, выполняются все колбэки, запланированные в ответ на I/O-события (а также уже запланированные), после чего происходит выход. Если [`stop()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.stop) вызывается во время выполнения [`run_forever()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_forever), то будет выполнен текущий набор колбэков, после чего произойдёт выход. Обратите внимание, что колбэки, запланированные другими колбэками, в этом случае не выполнятся; они выполнятся при следующем вызове [`run_forever()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_forever).3132Изменено в версии 3.5.1.3334#### `AbstractEventLoop.run_until_complete(future)`3536Выполняется до завершения [`Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future).3738Если аргумент является [объектом корутины](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), он оборачивается с помощью [`ensure_future()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.ensure_future).3940Возвращает результат Future или возбуждает его исключение.4142#### `AbstractEventLoop.is_running()`4344Возвращает статус выполнения цикла событий.4546#### `AbstractEventLoop.stop()`4748Останавливает выполнение цикла событий.4950Это приводит к выходу из [`run_forever()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_forever) при следующей удобной возможности (см. там подробнее).5152Изменено в версии 3.5.1.5354#### `AbstractEventLoop.is_closed()`5556Возвращает `True`, если цикл событий был закрыт.5758Новое в версии 3.4.2.5960#### `AbstractEventLoop.close()`6162Закрывает цикл событий. Цикл не должен выполняться. Ожидающие колбэки будут потеряны.6364Это очищает очереди и завершает работу исполнителя, но не дожидается его полной остановки.6566Это идемпотентно и необратимо. После этого метода не следует вызывать никакие другие методы.6768## 18.5.1.2. Вызовы6970Большинство функций [`asyncio`](https://python-all.ru/3.5/library/asyncio.html#module-asyncio) не принимают именованные аргументы. Если вы хотите передать именованные аргументы в свой колбэк, используйте [`functools.partial()`](https://python-all.ru/3.5/library/functools.html#functools.partial). Например, `loop.call_soon(functools.partial(print, "Hello", flush=True))` вызовет `print("Hello", flush=True)`.7172> **Примечание**73>74> [`functools.partial()`](https://python-all.ru/3.5/library/functools.html#functools.partial) лучше, чем функции `lambda`, потому что [`asyncio`](https://python-all.ru/3.5/library/asyncio.html#module-asyncio) может проверять объект [`functools.partial()`](https://python-all.ru/3.5/library/functools.html#functools.partial) для отображения параметров в режиме отладки, в то время как функции `lambda` имеют плохое представление.7576#### `AbstractEventLoop.call_soon(callback, *args)`7778Планирует вызов колбэка как можно скорее. Колбэк вызывается после возврата [`call_soon()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon), когда управление возвращается в цикл событий.7980Это работает как очередь FIFO: колбэки вызываются в порядке, в котором они зарегистрированы. Каждый колбэк вызывается ровно один раз.8182Любые позиционные аргументы, указанные после колбэка, будут переданы ему при вызове.8384Возвращается экземпляр [`asyncio.Handle`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.8586[Используйте functools.partial для передачи именованных аргументов в колбэк](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-pass-keywords).8788#### `AbstractEventLoop.call_soon_threadsafe(callback, *args)`8990Аналогично [`call_soon()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon), но потокобезопасно.9192См. раздел [concurrency and multithreading](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-multithreading) документации.9394## 18.5.1.3. Отложенные вызовы9596Цикл событий имеет собственные внутренние часы для вычисления тайм-аутов. Какие именно часы используются, зависит от реализации цикла событий (зависящей от платформы); в идеале это монотонные часы. Обычно это другие часы, нежели [`time.time()`](https://python-all.ru/3.5/library/time.html#time.time).9798> **Примечание**99>100> Тайм-ауты (относительная *задержка* или абсолютное *время*) не должны превышать одних суток.101102#### `AbstractEventLoop.call_later(delay, callback, *args)`103104Организует вызов *колбэка* через заданную *задержку* в секундах (целое число или float).105106Возвращается экземпляр [`asyncio.Handle`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.107108*Колбэк* будет вызван ровно один раз на каждый вызов [`call_later()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later). Если два колбэка запланированы на одно и то же время, порядок их вызова не определён.109110Необязательные позиционные *args* будут переданы колбэку при его вызове. Если нужно передать колбэку именованные аргументы, используйте замыкание или [`functools.partial()`](https://python-all.ru/3.5/library/functools.html#functools.partial).111112[Используйте functools.partial для передачи именованных аргументов в колбэк](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-pass-keywords).113114#### `AbstractEventLoop.call_at(when, callback, *args)`115116Организует вызов *колбэка* в указанную абсолютную метку времени *when* (целое число или float), используя ту же систему отсчёта времени, что и [`AbstractEventLoop.time()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.time).117118Поведение этого метода аналогично [`call_later()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later).119120Возвращается экземпляр [`asyncio.Handle`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.121122[Используйте functools.partial для передачи именованных аргументов в колбэк](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-pass-keywords).123124#### `AbstractEventLoop.time()`125126Возвращает текущее время в виде значения [`float`](https://python-all.ru/3.5/library/functions.html#float) в соответствии с внутренними часами цикла событий.127128> **См. также**129>130> Функция [`asyncio.sleep()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.sleep).131132## 18.5.1.4. Futures133134#### `AbstractEventLoop.create_future()`135136Создаёт объект [`asyncio.Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future), привязанный к циклу событий.137138Это предпочтительный способ создания Future-объектов в asyncio, поскольку реализации цикла событий могут предоставлять альтернативные реализации класса Future (с улучшенной производительностью или инструментарием).139140Новое в версии 3.5.2.141142## 18.5.1.5. Задачи143144#### `AbstractEventLoop.create_task(coro)`145146Планирует выполнение [корутинного объекта](https://python-all.ru/3.5/library/asyncio-task.html#coroutine): оборачивает его в future. Возвращает объект [`Task`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task).147148Сторонние циклы событий могут использовать собственный подкласс [`Task`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task) для взаимодействия. В этом случае тип результата – подкласс [`Task`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Task).149150Этот метод был добавлен в Python 3.4.2. Используйте функцию [`async()`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.async) для поддержки более старых версий Python.151152Новое в версии 3.4.2.153154#### `AbstractEventLoop.set_task_factory(factory)`155156Устанавливает фабрику задач, которая будет использоваться [`AbstractEventLoop.create_task()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_task).157158Если *factory* равно `None`, будет установлена фабрика задач по умолчанию.159160Если *factory* является *вызываемым объектом*, его сигнатура должна соответствовать `(loop, coro)`, где *loop* – ссылка на активный цикл событий, *coro* – объект корутины. Вызываемый объект должен возвращать объект, совместимый с [`asyncio.Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future).161162Новое в версии 3.4.4.163164#### `AbstractEventLoop.get_task_factory()`165166Возвращает фабрику задач или `None`, если используется стандартная.167168Новое в версии 3.4.4.169170## 18.5.1.6. Создание соединений171172#### `coroutine AbstractEventLoop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None)`173174Создаёт потоковое транспортное соединение с указанными интернет-хостом *host* и портом *port*: семейство сокетов [`AF_INET`](https://python-all.ru/3.5/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.5/library/socket.html#socket.AF_INET6) в зависимости от *host* (или *family*, если указано), тип сокета [`SOCK_STREAM`](https://python-all.ru/3.5/library/socket.html#socket.SOCK_STREAM). *protocol\_factory* должен быть вызываемым объектом, возвращающим экземпляр [протокола](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-protocol).175176Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), которая пытается установить соединение в фоновом режиме. В случае успеха корутина возвращает пару `(transport, protocol)`.177178Хронологическая последовательность выполняемой операции следующая:1791801. Соединение установлено, и создаётся [транспорт](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-transport), представляющий его.1812. *protocol\_factory* вызывается без аргументов и должен возвращать экземпляр [протокола](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-protocol).1823. Экземпляр протокола привязывается к транспорту, и вызывается его метод `connection_made()`.1834. Корутина успешно возвращает пару `(transport, protocol)`.184185Созданный транспорт является двунаправленным потоком, зависящим от реализации.186187> **Примечание**188>189> *protocol\_factory* может быть любым вызываемым объектом, не обязательно классом. Например, если нужно использовать уже созданный экземпляр протокола, можно передать `lambda: my_protocol`.190191Параметры, изменяющие способ создания соединения:192193- *ssl*: если указан и не равен false, создаётся SSL/TLS транспорт (по умолчанию создаётся обычный TCP транспорт). Если *ssl* является объектом [`ssl.SSLContext`](https://python-all.ru/3.5/library/ssl.html#ssl.SSLContext), этот контекст используется для создания транспорта; если *ssl* равен [`True`](https://python-all.ru/3.5/library/constants.html#True), используется контекст с некоторыми неопределёнными настройками по умолчанию.194195  > **См. также**196  >197  > [Вопросы безопасности SSL/TLS](https://python-all.ru/3.5/library/ssl.html#ssl-security)198- *server\_hostname* используется только вместе с *ssl* и задаёт или переопределяет имя хоста, с которым будет сравниваться сертификат целевого сервера. По умолчанию используется значение аргумента *host*. Если *host* пуст, значение по умолчанию отсутствует, и необходимо передать значение для *server\_hostname*. Если *server\_hostname* является пустой строкой, проверка имени хоста отключается (что представляет серьёзную угрозу безопасности, допуская атаки man-in-the-middle).199- *family*, *proto*, *flags* – необязательные семейство адресов, протокол и флаги, которые передаются в getaddrinfo() для разрешения *host*. Если заданы, все они должны быть целыми числами из соответствующих констант модуля [`socket`](https://python-all.ru/3.5/library/socket.html#module-socket).200- Если задан *sock*, он должен быть существующим, уже подключённым объектом [`socket.socket`](https://python-all.ru/3.5/library/socket.html#socket.socket), который будет использоваться транспортом. Если *sock* задан, ни один из параметров *host*, *port*, *family*, *proto*, *flags* и *local\_addr* не должен быть указан.201- *local\_addr*, если указан, представляет собой кортеж `(local_host, local_port)`, используемый для локальной привязки сокета. *local\_host* и *local\_port* ищутся с помощью getaddrinfo(), аналогично *host* и *port*.202203Изменено в версии 3.5: На Windows с [`ProactorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) теперь поддерживается SSL/TLS.204205> **См. также**206>207> Функция [`open_connection()`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.open_connection) может использоваться для получения пары ([`StreamReader`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.StreamReader), [`StreamWriter`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.StreamWriter)) вместо протокола.208209#### `coroutine AbstractEventLoop.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)`210211Создание датаграммного соединения: семейство сокетов [`AF_INET`](https://python-all.ru/3.5/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.5/library/socket.html#socket.AF_INET6) в зависимости от *host* (или *family*, если указано), тип сокета [`SOCK_DGRAM`](https://python-all.ru/3.5/library/socket.html#socket.SOCK_DGRAM). *protocol\_factory* должен быть вызываемым объектом, возвращающим экземпляр [протокола](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-protocol).212213Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), которая пытается установить соединение в фоновом режиме. В случае успеха корутина возвращает пару `(transport, protocol)`.214215Параметры, изменяющие способ создания соединения:216217- *local\_addr*, если задан, представляет собой кортеж `(local_host, local_port)`, используемый для привязки сокета локально. *local\_host* и *local\_port* разрешаются с помощью [`getaddrinfo()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo).218- *remote\_addr*, если задан, представляет собой кортеж `(remote_host, remote_port)`, используемый для подключения сокета к удалённому адресу. *remote\_host* и *remote\_port* разрешаются с помощью [`getaddrinfo()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo).219- *family*, *proto*, *flags* – необязательные семейство адресов, протокол и флаги, передаваемые в [`getaddrinfo()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo) для разрешения *host*. Если заданы, все они должны быть целыми числами из соответствующих констант модуля [`socket`](https://python-all.ru/3.5/library/socket.html#module-socket).220- *reuse\_address* указывает ядру повторно использовать локальный сокет в состоянии TIME\_WAIT, не дожидаясь истечения его естественного таймаута. Если не указано, автоматически устанавливается в `True` на UNIX.221- *reuse\_port* сообщает ядру, что данная конечная точка может быть привязана к тому же порту, что и другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Этот параметр не поддерживается в Windows и некоторых UNIX. Если константа `SO_REUSEPORT` не определена, эта возможность не поддерживается.222- *allow\_broadcast* указывает ядру разрешить этой конечной точке отправлять сообщения на широковещательный адрес.223- *sock* может быть указан необязательно, чтобы использовать уже существующий, подключённый объект [`socket.socket`](https://python-all.ru/3.5/library/socket.html#socket.socket) для транспорта. Если указан, *local\_addr* и *remote\_addr* должны быть опущены (должны быть [`None`](https://python-all.ru/3.5/library/constants.html#None)).224225В Windows с [`ProactorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) этот метод не поддерживается.226227См. примеры [протокол UDP-клиента эхо](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-udp-echo-client-protocol) и [протокол UDP-сервера эхо](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-udp-echo-server-protocol).228229#### `coroutine AbstractEventLoop.create_unix_connection(protocol_factory, path, *, ssl=None, sock=None, server_hostname=None)`230231Создание UNIX-соединения: семейство сокетов [`AF_UNIX`](https://python-all.ru/3.5/library/socket.html#socket.AF_UNIX), тип сокета [`SOCK_STREAM`](https://python-all.ru/3.5/library/socket.html#socket.SOCK_STREAM). Семейство сокетов [`AF_UNIX`](https://python-all.ru/3.5/library/socket.html#socket.AF_UNIX) используется для эффективного взаимодействия между процессами на одной машине.232233Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), которая пытается установить соединение в фоновом режиме. В случае успеха корутина возвращает пару `(transport, protocol)`.234235*path* – это имя сокета домена UNIX и требуется, если не указан параметр *sock*. Поддерживаются абстрактные UNIX-сокеты, пути [`str`](https://python-all.ru/3.5/library/stdtypes.html#str) и [`bytes`](https://python-all.ru/3.5/library/functions.html#bytes).236237О параметрах см. метод [`AbstractEventLoop.create_connection()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_connection).238239Доступность: UNIX.240241## 18.5.1.7. Создание прослушивающих соединений242243#### `coroutine AbstractEventLoop.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)`244245Создаёт TCP-сервер (тип сокета [`SOCK_STREAM`](https://python-all.ru/3.5/library/socket.html#socket.SOCK_STREAM)), привязанный к *host* и *port*.246247Возвращает объект [`Server`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Server), его атрибут [`sockets`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Server.sockets) содержит созданные сокеты. Используйте метод [`Server.close()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Server.close) для остановки сервера: закрыть слушающие сокеты.248249Параметры:250251- Параметр *host* может быть строкой; в этом случае TCP-сервер привязывается к *host* и *port*. Параметр *host* также может быть последовательностью строк, и тогда TCP-сервер привязывается ко всем хостам из этой последовательности. Если *host* – пустая строка или `None`, подразумеваются все интерфейсы, и будет возвращён список из нескольких сокетов (скорее всего, один для IPv4 и один для IPv6).252- *family* можно установить в [`socket.AF_INET`](https://python-all.ru/3.5/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.5/library/socket.html#socket.AF_INET6), чтобы заставить сокет использовать IPv4 или IPv6. Если не установлено, значение будет определено из host (по умолчанию `socket.AF_UNSPEC`).253- *flags* – битовая маска для [`getaddrinfo()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo).254- *sock* можно указать, чтобы использовать уже существующий объект сокета. Если он указан, *host* и *port* следует опустить (они должны быть [`None`](https://python-all.ru/3.5/library/constants.html#None)).255- *backlog* – максимальное количество соединений в очереди, передаваемое в [`listen()`](https://python-all.ru/3.5/library/socket.html#socket.socket.listen) (по умолчанию 100).256- *ssl* можно установить в [`SSLContext`](https://python-all.ru/3.5/library/ssl.html#ssl.SSLContext), чтобы включить SSL для принятых соединений.257- *reuse\_address* указывает ядру повторно использовать локальный сокет в состоянии TIME\_WAIT, не дожидаясь истечения его естественного таймаута. Если не указано, автоматически устанавливается в `True` на UNIX.258- *reuse\_port* указывает ядру разрешить привязку этой конечной точки к тому же порту, к которому привязаны другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Эта опция не поддерживается в Windows.259260Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).261262Изменено в версии 3.5: На Windows с [`ProactorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) теперь поддерживается SSL/TLS.263264> **См. также**265>266> Функция [`start_server()`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.start_server) создаёт пару ([`StreamReader`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.StreamReader), [`StreamWriter`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.StreamWriter)) и вызывает колбэк с этой парой.267268Изменено в версии 3.5.1: Параметр *host* теперь может быть последовательностью строк.269270#### `coroutine AbstractEventLoop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None)`271272Аналогично [`AbstractEventLoop.create_server()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_server), но для семейства сокетов [`AF_UNIX`](https://python-all.ru/3.5/library/socket.html#socket.AF_UNIX).273274Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).275276Доступность: UNIX.277278#### `coroutine BaseEventLoop.connect_accepted_socket(protocol_factory, sock, *, ssl=None)`279280Обработать принятое соединение.281282Это используется серверами, которые принимают соединения вне asyncio, но используют asyncio для их обработки.283284Параметры:285286- *sock* – это уже существующий объект сокета, возвращённый вызовом `accept`.287- *ssl* можно установить в [`SSLContext`](https://python-all.ru/3.5/library/ssl.html#ssl.SSLContext), чтобы включить SSL для принятых соединений.288289Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine). После завершения корутина возвращает пару `(transport, protocol)`.290291## 18.5.1.8. Отслеживание файловых дескрипторов292293На Windows с [`SelectorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) поддерживаются только дескрипторы сокетов (например, файловые дескрипторы каналов не поддерживаются).294295На Windows с [`ProactorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) эти методы не поддерживаются.296297#### `AbstractEventLoop.add_reader(fd, callback, *args)`298299Начать наблюдение за файловым дескриптором на готовность к чтению и затем вызвать *колбэк* с указанными аргументами.300301[Используйте functools.partial для передачи именованных аргументов в колбэк](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-pass-keywords).302303#### `AbstractEventLoop.remove_reader(fd)`304305Прекратить наблюдение за файловым дескриптором на готовность к чтению.306307#### `AbstractEventLoop.add_writer(fd, callback, *args)`308309Начать наблюдение за файловым дескриптором на готовность к записи и затем вызвать *колбэк* с указанными аргументами.310311[Используйте functools.partial для передачи именованных аргументов в колбэк](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-pass-keywords).312313#### `AbstractEventLoop.remove_writer(fd)`314315Прекратить наблюдение за файловым дескриптором на готовность к записи.316317Пример [наблюдения за файловым дескриптором на события чтения](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-watch-read-event) использует низкоуровневый метод [`AbstractEventLoop.add_reader()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_reader) для регистрации файлового дескриптора сокета.318319## 18.5.1.9. Низкоуровневые операции с сокетами320321#### `coroutine AbstractEventLoop.sock_recv(sock, nbytes)`322323Получает данные из сокета. Аналогично блокирующему методу [`socket.socket.recv()`](https://python-all.ru/3.5/library/socket.html#socket.socket.recv).324325Возвращаемое значение – объект bytes, представляющий полученные данные. Максимальный объём данных, который можно получить за один раз, задаётся параметром *nbytes*.326327В [`SelectorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий сокет *sock* должен быть неблокирующим.328329Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).330331#### `coroutine AbstractEventLoop.sock_sendall(sock, data)`332333Отправляет данные в сокет. Аналогично блокирующему методу [`socket.socket.sendall()`](https://python-all.ru/3.5/library/socket.html#socket.socket.sendall).334335Сокет должен быть подключён к удалённому сокету. Этот метод продолжает отправлять данные из *data*, пока либо не будут отправлены все данные, либо не произойдёт ошибка. В случае успеха возвращается `None`. При ошибке возникает исключение, и невозможно определить, сколько данных (если вообще какие-то) было успешно обработано принимающей стороной соединения.336337В [`SelectorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий сокет *sock* должен быть неблокирующим.338339Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).340341#### `coroutine AbstractEventLoop.sock_connect(sock, address)`342343Подключается к удалённому сокету по адресу *address*. Аналогично блокирующему методу [`socket.socket.connect()`](https://python-all.ru/3.5/library/socket.html#socket.socket.connect).344345В [`SelectorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий сокет *sock* должен быть неблокирующим.346347Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).348349Изменено в версии 3.5.2: `address` больше не требует разрешения. `sock_connect` попытается проверить, разрешён ли уже *address*, вызвав [`socket.inet_pton()`](https://python-all.ru/3.5/library/socket.html#socket.inet_pton). Если нет, [`AbstractEventLoop.getaddrinfo()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.getaddrinfo) будет использован для разрешения *address*.350351> **См. также**352>353> [`AbstractEventLoop.create_connection()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_connection) и [`asyncio.open_connection()`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.open_connection).354355#### `coroutine AbstractEventLoop.sock_accept(sock)`356357Принимает соединение. Аналогично блокирующему [`socket.socket.accept()`](https://python-all.ru/3.5/library/socket.html#socket.socket.accept).358359Сокет должен быть привязан к адресу и ожидать подключения. Возвращаемое значение – пара `(conn, address)`, где *conn* – это *новый* объект сокета, пригодный для отправки и получения данных по соединению, а *address* – адрес, привязанный к сокету на другом конце соединения.360361Сокет *sock* должен быть неблокирующим.362363Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).364365> **См. также**366>367> [`AbstractEventLoop.create_server()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_server) и [`start_server()`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.start_server).368369## 18.5.1.10. Разрешение имени хоста370371#### `coroutine AbstractEventLoop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0)`372373Этот метод – [корутина](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), аналогичная функции [`socket.getaddrinfo()`](https://python-all.ru/3.5/library/socket.html#socket.getaddrinfo), но неблокирующая.374375#### `coroutine AbstractEventLoop.getnameinfo(sockaddr, flags=0)`376377Этот метод – [корутина](https://python-all.ru/3.5/library/asyncio-task.html#coroutine), аналогичная функции [`socket.getnameinfo()`](https://python-all.ru/3.5/library/socket.html#socket.getnameinfo), но неблокирующая.378379## 18.5.1.11. Подключение каналов380381В Windows с [`SelectorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) эти методы не поддерживаются. Используйте [`ProactorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.ProactorEventLoop) для поддержки каналов в Windows.382383#### `coroutine AbstractEventLoop.connect_read_pipe(protocol_factory, pipe)`384385Регистрирует канал чтения в цикле событий.386387*protocol\_factory* должен создавать объект с интерфейсом [`Protocol`](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio.Protocol). *pipe* – это [объект, подобный файлу](https://python-all.ru/3.5/glossary.html#term-file-object). Возвращает пару `(transport, protocol)`, где *транспорт* поддерживает интерфейс [`ReadTransport`](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio.ReadTransport).388389При [`SelectorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий канал *pipe* переводится в неблокирующий режим.390391Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).392393#### `coroutine AbstractEventLoop.connect_write_pipe(protocol_factory, pipe)`394395Регистрирует канал записи в цикле событий.396397*protocol\_factory* должен создавать объект с интерфейсом `BaseProtocol`. *pipe* – это [объект, подобный файлу](https://python-all.ru/3.5/glossary.html#term-file-object). Возвращает пару `(transport, protocol)`, где *транспорт* поддерживает интерфейс [`WriteTransport`](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio.WriteTransport).398399При [`SelectorEventLoop`](https://python-all.ru/3.5/library/asyncio-eventloops.html#asyncio.SelectorEventLoop) цикле событий канал *pipe* переводится в неблокирующий режим.400401Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).402403> **См. также**404>405> Методы [`AbstractEventLoop.subprocess_exec()`](https://python-all.ru/3.5/library/asyncio-subprocess.html#asyncio.AbstractEventLoop.subprocess_exec) и [`AbstractEventLoop.subprocess_shell()`](https://python-all.ru/3.5/library/asyncio-subprocess.html#asyncio.AbstractEventLoop.subprocess_shell).406407## 18.5.1.12. Сигналы UNIX408409Доступно: только UNIX.410411#### `AbstractEventLoop.add_signal_handler(signum, callback, *args)`412413Добавляет обработчик сигнала.414415Вызывает [`ValueError`](https://python-all.ru/3.5/library/exceptions.html#ValueError), если номер сигнала недопустим или его невозможно перехватить. Вызывает [`RuntimeError`](https://python-all.ru/3.5/library/exceptions.html#RuntimeError), если возникла проблема при установке обработчика.416417[Используйте functools.partial для передачи именованных аргументов в колбэк](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-pass-keywords).418419#### `AbstractEventLoop.remove_signal_handler(sig)`420421Удаляет обработчик сигнала.422423Возвращает `True`, если обработчик сигнала был удалён, и `False` в противном случае.424425> **См. также**426>427> Модуль [`signal`](https://python-all.ru/3.5/library/signal.html#module-signal).428429## 18.5.1.13. Исполнитель430431Вызывает функцию в [`Executor`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.Executor) (пуле потоков или пуле процессов). По умолчанию цикл событий использует исполнитель с пулом потоков ([`ThreadPoolExecutor`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)).432433#### `coroutine AbstractEventLoop.run_in_executor(executor, func, *args)`434435Планирует вызов функции *func* в указанном исполнителе.436437Аргумент *исполнитель* должен быть экземпляром [`Executor`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.Executor) Исполнитель по умолчанию используется, если *исполнитель* равен `None`.438439[Используйте functools.partial для передачи именованных аргументов в \*func\*](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio-pass-keywords).440441Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).442443Изменено в версии 3.5.3: `BaseEventLoop.run_in_executor()` больше не настраивает `max_workers` создаваемого исполнителя пула потоков, оставляя настройку по умолчанию самому исполнителю пула потоков ([`ThreadPoolExecutor`](https://python-all.ru/3.5/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)).444445#### `AbstractEventLoop.set_default_executor(executor)`446447Устанавливает исполнитель по умолчанию, используемый [`run_in_executor()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.run_in_executor).448449## 18.5.1.14. API обработки ошибок450451Позволяет настраивать обработку исключений в цикле событий.452453#### `AbstractEventLoop.set_exception_handler(handler)`454455Устанавливает *handler* в качестве нового обработчика исключений цикла событий.456457Если *handler* равен `None`, будет установлен обработчик исключений по умолчанию.458459Если *handler* – вызываемый объект, его сигнатура должна совпадать с `(loop, context)`, где `loop` будет ссылкой на активный цикл событий, `context` будет объектом `dict` (см. документацию [`call_exception_handler()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_exception_handler) для подробностей о контексте).460461#### `AbstractEventLoop.get_exception_handler()`462463Возвращает обработчик исключений или `None`, если используется стандартный.464465Новое в версии 3.5.2.466467#### `AbstractEventLoop.default_exception_handler(context)`468469Обработчик исключений по умолчанию.470471Вызывается при возникновении исключения, когда не установлен обработчик исключений, а также может вызываться пользовательским обработчиком исключений, который хочет передать управление стандартному поведению.472473Параметр *context* имеет то же значение, что и в [`call_exception_handler()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_exception_handler).474475#### `AbstractEventLoop.call_exception_handler(context)`476477Вызывает обработчик исключений текущего цикла событий.478479*context* – объект `dict`, содержащий следующие ключи (новые ключи могут быть добавлены позже):480481- ‘message’: сообщение об ошибке;482- 'исключение' (необязательно): объект исключения;483- ‘future’ (необязательно): экземпляр [`asyncio.Future`](https://python-all.ru/3.5/library/asyncio-task.html#asyncio.Future);484- ‘handle’ (необязательно): экземпляр [`asyncio.Handle`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Handle);485- 'протокол' (необязательно): экземпляр [Protocol](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-protocol);486- 'транспорт' (необязательно): экземпляр [Transport](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-transport);487- ‘socket’ (необязательно): экземпляр [`socket.socket`](https://python-all.ru/3.5/library/socket.html#socket.socket).488489> **Примечание**490>491> Примечание: этот метод не следует переопределять в подклассах циклов событий. Для любой пользовательской обработки исключений используйте метод [`set_exception_handler()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.set_exception_handler).492493## 18.5.1.15. Режим отладки494495#### `AbstractEventLoop.get_debug()`496497Возвращает режим отладки ([`bool`](https://python-all.ru/3.5/library/functions.html#bool)) цикла событий.498499Значение по умолчанию – `True`, если переменная окружения [`PYTHONASYNCIODEBUG`](https://python-all.ru/3.5/using/cmdline.html#envvar-PYTHONASYNCIODEBUG) имеет непустое строковое значение, и `False` в противном случае.500501Новое в версии 3.4.2.502503#### `AbstractEventLoop.set_debug(enabled: bool)`504505Устанавливает режим отладки цикла событий.506507Новое в версии 3.4.2.508509> **См. также**510>511> [Режим отладки asyncio](https://python-all.ru/3.5/library/asyncio-dev.html#asyncio-debug-mode).512513## 18.5.1.16. Сервер514515#### `class asyncio.Server`516517Сервер, прослушивающий сокеты.518519Объект, создаваемый методом [`AbstractEventLoop.create_server()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_server) и функцией [`start_server()`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.start_server). Не создавайте экземпляр класса напрямую.520521#### `close()`522523Прекращает обслуживание: закрывает слушающие сокеты и устанавливает атрибут [`sockets`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Server.sockets) в `None`.524525Сокеты существующих входящих подключений клиентов остаются открытыми.526527Сервер закрывается асинхронно, используйте [`wait_closed()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Server.wait_closed)\\nкорутину, чтобы дождаться закрытия сервера.528529#### `coroutine wait_closed()`530531Ожидайте завершения метода [`close()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.Server.close).532533Этот метод является [корутиной](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).534535#### `sockets`536537Список объектов [`socket.socket`](https://python-all.ru/3.5/library/socket.html#socket.socket), которые прослушивает сервер, или `None`, если сервер закрыт.538539## 18.5.1.17. Handle540541#### `class asyncio.Handle`542543Объект-обёртка колбэка, возвращаемый функциями [`AbstractEventLoop.call_soon()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon), [`AbstractEventLoop.call_soon_threadsafe()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon_threadsafe), [`AbstractEventLoop.call_later()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later) и [`AbstractEventLoop.call_at()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_at).544545#### `cancel()`546547Отменяет вызов. Если колбэк уже отменён или выполнен, этот метод ничего не делает.548549## 18.5.1.18. Примеры циклов событий550551### 18.5.1.18.1. Hello World с помощью call\_soon()552553Пример использования метода [`AbstractEventLoop.call_soon()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_soon) для планирования колбэка. Колбэк выводит `"Hello World"` и затем останавливает цикл событий:554555```python556import asyncio557558def hello_world(loop):559    print('Hello World')560    loop.stop()561562loop = asyncio.get_event_loop()563564# Запланировать вызов hello_world()565loop.call_soon(hello_world, loop)566567# Блокирующий вызов прерван loop.stop()568loop.run_forever()569loop.close()570```571572> **См. также**573>574> Пример [корутины Hello World](https://python-all.ru/3.5/library/asyncio-task.html#asyncio-hello-world-coroutine) использует [корутину](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).575576### 18.5.1.18.2. Отображение текущей даты с помощью call\_later()577578Пример колбэка, который каждую секунду выводит текущую дату. Колбэк использует метод [`AbstractEventLoop.call_later()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.call_later), чтобы перепланировать себя на 5 секунд, а затем останавливает цикл событий:579580```python581import asyncio582import datetime583584def display_date(end_time, loop):585    print(datetime.datetime.now())586    if (loop.time() + 1.0) < end_time:587        loop.call_later(1, display_date, end_time, loop)588    else:589        loop.stop()590591loop = asyncio.get_event_loop()592593# Запланировать первый вызов display_date()594end_time = loop.time() + 5.0595loop.call_soon(display_date, end_time, loop)596597# Блокирующий вызов прерван loop.stop()598loop.run_forever()599loop.close()600```601602> **См. также**603>604> Пример [корутины, отображающей текущую дату](https://python-all.ru/3.5/library/asyncio-task.html#asyncio-date-coroutine) использует [корутину](https://python-all.ru/3.5/library/asyncio-task.html#coroutine).605606### 18.5.1.18.3. Слежение за файловым дескриптором на события чтения607608Ожидание, пока файловый дескриптор не получит некоторые данные, с помощью метода [`AbstractEventLoop.add_reader()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_reader), после чего цикл событий закрывается:609610```python611import asyncio612try:613    from socket import socketpair614except ImportError:615    from asyncio.windows_utils import socketpair616617# Создать пару связанных файловых дескрипторов618rsock, wsock = socketpair()619loop = asyncio.get_event_loop()620621def reader():622    data = rsock.recv(100)623    print("Received:", data.decode())624    # Готово: отменить регистрацию файлового дескриптора625    loop.remove_reader(rsock)626    # Остановить цикл событий627    loop.stop()628629# Зарегистрировать файловый дескриптор для события чтения630loop.add_reader(rsock, reader)631632# Симулировать приём данных из сети633loop.call_soon(wsock.send, 'abc'.encode())634635# Запустить цикл событий636loop.run_forever()637638# Готово, закрыть сокеты и цикл событий.639rsock.close()640wsock.close()641loop.close()642```643644> **См. также**645>646> Пример [регистрации открытого сокета для ожидания данных с помощью протокола](https://python-all.ru/3.5/library/asyncio-protocol.html#asyncio-register-socket) использует низкоуровневый протокол, созданный методом [`AbstractEventLoop.create_connection()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_connection).647>648> В примере [регистрации открытого сокета для ожидания данных с помощью потоков](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio-register-socket-streams) используются высокоуровневые потоки , созданные функцией [`open_connection()`](https://python-all.ru/3.5/library/asyncio-stream.html#asyncio.open_connection) в корутине.649650### 18.5.1.18.4. Установка обработчиков сигналов SIGINT и SIGTERM651652Зарегистрировать обработчики для сигналов `SIGINT` и `SIGTERM` с помощью метода [`AbstractEventLoop.add_signal_handler()`](https://python-all.ru/3.5/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.add_signal_handler):653654```python655import asyncio656import functools657import os658import signal659660def ask_exit(signame):661    print("got signal %s: exit" % signame)662    loop.stop()663664loop = asyncio.get_event_loop()665for signame in ('SIGINT', 'SIGTERM'):666    loop.add_signal_handler(getattr(signal, signame),667                            functools.partial(ask_exit, signame))668669print("Event loop running forever, press Ctrl+C to interrupt.")670print("pid %s: send SIGINT or SIGTERM to exit." % os.getpid())671try:672    loop.run_forever()673finally:674    loop.close()675```676677Этот пример работает только на UNIX.678