asyncio-eventloop.md
1> **Источник:** https://python-all.ru/3.11/library/asyncio-eventloop.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Цикл событий89**Исходный код:** [Lib/asyncio/events.py](https://python-all.ru/src/3.11/Lib/asyncio/events.py), [Lib/asyncio/base\_events.py](https://python-all.ru/src/3.11/Lib/asyncio/base_events.py)1011---1213Предисловие1415Цикл событий – ядро каждого приложения asyncio. Циклы событий выполняют асинхронные задачи и колбэки, осуществляют сетевые операции ввода-вывода и запускают подпроцессы.1617Разработчикам приложений обычно следует использовать высокоуровневые функции asyncio, такие как [`asyncio.run()`](https://python-all.ru/3.11/library/asyncio-runner.html#asyncio.run), и редко требуется обращаться к объекту цикла или вызывать его методы. Этот раздел предназначен в основном для авторов низкоуровневого кода, библиотек и фреймворков, которым нужен более тонкий контроль над поведением цикла событий.1819Получение цикла событий2021Следующие низкоуровневые функции можно использовать для получения, установки или создания цикла событий:2223#### `asyncio.get_running_loop()`2425Возвращает работающий цикл событий в текущем потоке ОС.2627Возбуждает [`RuntimeError`](https://python-all.ru/3.11/library/exceptions.html#RuntimeError), если нет работающего цикла событий.2829Эту функцию можно вызывать только из корутины или колбэка.3031Добавлено в версии 3.7.3233#### `asyncio.get_event_loop()`3435Получить текущий цикл событий.3637При вызове из корутины или колбэка (например, запланированного с помощью call\_soon или аналогичного API), эта функция всегда возвращает работающий цикл событий.3839Если не установлен выполняющийся цикл событий, функция вернёт результат вызова `get_event_loop_policy().get_event_loop()`.4041Поскольку поведение этой функции довольно сложное (особенно при использовании пользовательских политик цикла событий), в корутинах и колбэках предпочтительнее использовать функцию [`get_running_loop()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.get_running_loop), а не [`get_event_loop()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.get_event_loop).4243Как отмечено выше, рассмотрите использование высокоуровневой функции [`asyncio.run()`](https://python-all.ru/3.11/library/asyncio-runner.html#asyncio.run) вместо использования этих низкоуровневых функций для ручного создания и закрытия цикла событий.4445> **Примечание**46>47> В версиях Python 3.10.0–3.10.8 и 3.11.0 эта функция (и другие функции, которые используют её неявно) выдавала [`DeprecationWarning`](https://python-all.ru/3.11/library/exceptions.html#DeprecationWarning), если не было запущенного цикла событий, даже если текущий цикл был установлен в политике. В версиях Python 3.10.9, 3.11.1 и 3.12 они выдают [`DeprecationWarning`](https://python-all.ru/3.11/library/exceptions.html#DeprecationWarning), если нет запущенного цикла событий и не установлен текущий цикл. В одной из будущих версий Python это станет ошибкой.4849#### `asyncio.set_event_loop(loop)`5051Устанавливает *loop* в качестве текущего цикла событий для текущего потока ОС.5253#### `asyncio.new_event_loop()`5455Создаёт и возвращает новый объект цикла событий.5657Обратите внимание, что поведение функций [`get_event_loop()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.get_event_loop), [`set_event_loop()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.set_event_loop) и [`new_event_loop()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.new_event_loop) можно изменить, [установив пользовательскую политику цикла событий](https://python-all.ru/3.11/library/asyncio-policy.html#asyncio-policies).5859Содержание6061Эта страница документации содержит следующие разделы:6263- Раздел [Методы цикла событий](https://python-all.ru/3.11/library/asyncio-eventloop.html#event-loop-methods) – это справочная документация по API цикла событий;64- Раздел [Обработчики колбэков](https://python-all.ru/3.11/library/asyncio-eventloop.html#callback-handles) документирует экземпляры [`Handle`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Handle) и [`TimerHandle`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.TimerHandle), которые возвращаются из методов планирования, таких как [`loop.call_soon()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_soon) и [`loop.call_later()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_later);65- Раздел [Объекты сервера](https://python-all.ru/3.11/library/asyncio-eventloop.html#server-objects) документирует типы, возвращаемые методами цикла событий, такими как [`loop.create_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_server);66- Раздел [Реализации цикла событий](https://python-all.ru/3.11/library/asyncio-eventloop.html#event-loop-implementations) документирует классы [`SelectorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.SelectorEventLoop) и [`ProactorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.ProactorEventLoop);67- Раздел [Примеры](https://python-all.ru/3.11/library/asyncio-eventloop.html#examples) показывает, как работать с некоторыми API цикла событий.6869## Методы цикла событий7071Циклы событий имеют **низкоуровневые** API для следующего:7273[Запуск и остановка цикла событий](https://python-all.ru/3.11/library/asyncio-eventloop.html#running-and-stopping-the-loop) [Планирование колбэков](https://python-all.ru/3.11/library/asyncio-eventloop.html#scheduling-callbacks) [Планирование отложенных колбэков](https://python-all.ru/3.11/library/asyncio-eventloop.html#scheduling-delayed-callbacks) [Создание Future и задач](https://python-all.ru/3.11/library/asyncio-eventloop.html#creating-futures-and-tasks) [Открытие сетевых соединений](https://python-all.ru/3.11/library/asyncio-eventloop.html#opening-network-connections) [Создание сетевых серверов](https://python-all.ru/3.11/library/asyncio-eventloop.html#creating-network-servers) [Передача файлов](https://python-all.ru/3.11/library/asyncio-eventloop.html#transferring-files) [Обновление TLS](https://python-all.ru/3.11/library/asyncio-eventloop.html#tls-upgrade) [Наблюдение за файловыми дескрипторами](https://python-all.ru/3.11/library/asyncio-eventloop.html#watching-file-descriptors) [Работа с объектами сокетов напрямую](https://python-all.ru/3.11/library/asyncio-eventloop.html#working-with-socket-objects-directly) [DNS](https://python-all.ru/3.11/library/asyncio-eventloop.html#dns) [Работа с каналами](https://python-all.ru/3.11/library/asyncio-eventloop.html#working-with-pipes) [Сигналы Unix](https://python-all.ru/3.11/library/asyncio-eventloop.html#unix-signals) [Выполнение кода в пулах потоков или процессов](https://python-all.ru/3.11/library/asyncio-eventloop.html#executing-code-in-thread-or-process-pools) [API обработки ошибок](https://python-all.ru/3.11/library/asyncio-eventloop.html#error-handling-api) [Включение режима отладки](https://python-all.ru/3.11/library/asyncio-eventloop.html#enabling-debug-mode) [Запуск подпроцессов](https://python-all.ru/3.11/library/asyncio-eventloop.html#running-subprocesses)7475### [Запуск и остановка цикла](https://python-all.ru/3.11/library/asyncio-eventloop.html#id1)7677#### `loop.run_until_complete(future)`7879Выполняется до тех пор, пока *future* (экземпляр [`Future`](https://python-all.ru/3.11/library/asyncio-future.html#asyncio.Future)) не завершится.8081Если аргумент является [объектом корутины](https://python-all.ru/3.11/library/asyncio-task.html#coroutine), он неявно планируется для выполнения как [`asyncio.Task`](https://python-all.ru/3.11/library/asyncio-task.html#asyncio.Task).8283Возвращает результат Future или возбуждает его исключение.8485#### `loop.run_forever()`8687Запускает цикл событий до вызова [`stop()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.stop).8889Если [`stop()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.stop) вызывается до вызова [`run_forever()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.run_forever), цикл один раз опросит I/O-селектор с нулевым таймаутом, выполнит все колбэки, запланированные в ответ на события ввода-вывода (и уже запланированные), а затем завершится.9091Если [`stop()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.stop) вызывается во время выполнения [`run_forever()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.run_forever), цикл выполнит текущий пакет колбэков и завершится. Обратите внимание: новые колбэки, запланированные другими колбэками, в этом случае не запустятся; вместо этого они будут выполнены при следующем вызове [`run_forever()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.run_forever) или [`run_until_complete()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.run_until_complete).9293#### `loop.stop()`9495Останавливает цикл событий.9697#### `loop.is_running()`9899Возвращает `True`, если цикл событий в данный момент выполняется.100101#### `loop.is_closed()`102103Возвращает `True`, если цикл событий был закрыт.104105#### `loop.close()`106107Закрывает цикл событий.108109Цикл не должен выполняться при вызове этой функции. Все ожидающие колбэки будут отброшены.110111Этот метод очищает все очереди и завершает работу исполнителя, но не ожидает завершения исполнителя.112113Этот метод идемпотентен и необратим. После закрытия цикла событий не следует вызывать другие методы.114115#### `coroutine loop.shutdown_asyncgens()`116117Планирует закрытие всех открытых [асинхронных генераторов](https://python-all.ru/3.11/glossary.html#term-asynchronous-generator) с помощью вызова [`aclose()`](https://python-all.ru/3.11/reference/expressions.html#agen.aclose). После вызова этого метода цикл событий будет выдавать предупреждение, если выполняется итерация нового асинхронного генератора. Это следует использовать для надёжного завершения всех запланированных асинхронных генераторов.118119Обратите внимание: вызывать эту функцию не нужно, если используется [`asyncio.run()`](https://python-all.ru/3.11/library/asyncio-runner.html#asyncio.run).120121Пример:122123```python124try:125 loop.run_forever()126finally:127 loop.run_until_complete(loop.shutdown_asyncgens())128 loop.close()129```130131Новое в версии 3.6.132133#### `coroutine loop.shutdown_default_executor()`134135Планирует закрытие исполнителя по умолчанию и ожидает завершения всех потоков в [`ThreadPoolExecutor`](https://python-all.ru/3.11/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor). Как только этот метод будет вызван, использование исполнителя по умолчанию с [`loop.run_in_executor()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.run_in_executor) приведёт к возникновению [`RuntimeError`](https://python-all.ru/3.11/library/exceptions.html#RuntimeError).136137> **Примечание**138>139> Не следует вызывать этот метод при использовании [`asyncio.run()`](https://python-all.ru/3.11/library/asyncio-runner.html#asyncio.run), так как последний обрабатывает завершение исполнителя по умолчанию автоматически.140141Новое в версии 3.9.142143### [Планирование колбэков](https://python-all.ru/3.11/library/asyncio-eventloop.html#id2)144145#### `loop.call_soon(callback, *args, context=None)`146147Планирует вызов *колбэк* [колбэк](https://python-all.ru/3.11/glossary.html#term-callback) с аргументами *args* на следующей итерации цикла событий.148149Возвращает экземпляр [`asyncio.Handle`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Handle), который можно использовать для отмены колбэка.150151Колбэки вызываются в порядке их регистрации. Каждый колбэк будет вызван ровно один раз.152153Необязательный аргумент *context* (только ключевое слово) задаёт пользовательский [`contextvars.Context`](https://python-all.ru/3.11/library/contextvars.html#contextvars.Context) для выполнения *колбэк*. Если *context* не указан, используется текущий контекст.154155В отличие от [`call_soon_threadsafe()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_soon_threadsafe), этот метод не является потокобезопасным.156157#### `loop.call_soon_threadsafe(callback, *args, context=None)`158159Потокобезопасный вариант [`call_soon()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_soon). При планировании колбэков из другого потока *обязательно* использовать эту функцию, так как [`call_soon()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_soon) не является потокобезопасным.160161Возбуждает [`RuntimeError`](https://python-all.ru/3.11/library/exceptions.html#RuntimeError), если вызван на закрытом цикле событий. Это может произойти во вторичном потоке при завершении главного приложения.162163См. раздел [concurrency and multithreading](https://python-all.ru/3.11/library/asyncio-dev.html#asyncio-multithreading) документации.164165Изменено в версии 3.7: Добавлен параметр *context* (только ключевое слово). Подробнее см. [**PEP 567**](https://python-all.ru/3.11/library/asyncio-eventloop.html).166167> **Примечание**168>169> Большинство функций планирования [`asyncio`](https://python-all.ru/3.11/library/asyncio.html#module-asyncio) не позволяют передавать именованные аргументы. Для этого используйте [`functools.partial()`](https://python-all.ru/3.11/library/functools.html#functools.partial):170>171> ```python172> # запланирует "print("Hello", flush=True)"173> loop.call_soon(174> functools.partial(print, "Hello", flush=True))175> ```176>177> Использование partial-объектов обычно удобнее лямбд, так как asyncio может лучше отображать partial-объекты в сообщениях отладки и ошибок.178179### [Планирование отложенных колбэков](https://python-all.ru/3.11/library/asyncio-eventloop.html#id3)180181Цикл событий предоставляет механизмы для планирования вызова функций-колбэков в некоторый момент в будущем. Цикл событий использует монотонные часы для отслеживания времени.182183#### `loop.call_later(delay, callback, *args, context=None)`184185Планирует вызов *колбэк* через заданное количество секунд *delay* (может быть целым числом или числом с плавающей запятой).186187Возвращается экземпляр [`asyncio.TimerHandle`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.TimerHandle), который можно использовать для отмены колбэка.188189*колбэк* будет вызван ровно один раз. Если два колбэка запланированы на одно и то же время, порядок их вызова не определён.190191Необязательные позиционные аргументы *args* будут переданы колбэку при его вызове. Если нужно передать колбэку именованные аргументы, используйте [`functools.partial()`](https://python-all.ru/3.11/library/functools.html#functools.partial).192193Необязательный аргумент *context* (только ключевой) позволяет указать пользовательский [`contextvars.Context`](https://python-all.ru/3.11/library/contextvars.html#contextvars.Context) для выполнения *колбэка*. Если *context* не указан, используется текущий контекст.194195Изменено в версии 3.7: Добавлен параметр *context* (только ключевое слово). Подробнее см. [**PEP 567**](https://python-all.ru/3.11/library/asyncio-eventloop.html).196197Изменено в версии 3.8: В Python 3.7 и более ранних версиях с реализацией цикла событий по умолчанию параметр *delay* не мог превышать одного дня. В Python 3.8 это исправлено.198199#### `loop.call_at(when, callback, *args, context=None)`200201Планирует вызов *колбэк* в заданную абсолютную временную метку *when* (целое число или число с плавающей запятой), используя ту же временную шкалу, что и [`loop.time()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.time).202203Поведение этого метода аналогично [`call_later()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_later).204205Возвращается экземпляр [`asyncio.TimerHandle`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.TimerHandle), который можно использовать для отмены колбэка.206207Изменено в версии 3.7: Добавлен параметр *context* (только ключевое слово). Подробнее см. [**PEP 567**](https://python-all.ru/3.11/library/asyncio-eventloop.html).208209Изменено в версии 3.8: В Python 3.7 и более ранних версиях с реализацией цикла событий по умолчанию разность между *when* и текущим временем не могла превышать одного дня. В Python 3.8 это исправлено.210211#### `loop.time()`212213Возвращает текущее время, как значение [`float`](https://python-all.ru/3.11/library/functions.html#float), в соответствии с внутренними монотонными часами цикла событий.214215> **Примечание**216>217> Изменено в версии 3.8: В Python 3.7 и более ранних версиях таймауты (относительная *задержка* или абсолютное значение *when*) не должны были превышать одного дня. Это было исправлено в Python 3.8.218219> **См. также**220>221> Функция [`asyncio.sleep()`](https://python-all.ru/3.11/library/asyncio-task.html#asyncio.sleep).222223### [Создание Future и задач](https://python-all.ru/3.11/library/asyncio-eventloop.html#id4)224225#### `loop.create_future()`226227Создаёт объект [`asyncio.Future`](https://python-all.ru/3.11/library/asyncio-future.html#asyncio.Future), привязанный к циклу событий.228229Это предпочтительный способ создания Future в asyncio. Он позволяет сторонним циклам событий предоставлять альтернативные реализации объекта Future (с лучшей производительностью или инструментарием).230231Новое в версии 3.5.2.232233#### `loop.create_task(coro, *, name=None, context=None)`234235Планирует выполнение [корутины](https://python-all.ru/3.11/library/asyncio-task.html#coroutine) *coro*. Возвращает объект [`Task`](https://python-all.ru/3.11/library/asyncio-task.html#asyncio.Task).236237Сторонние циклы событий могут использовать свой собственный подкласс [`Task`](https://python-all.ru/3.11/library/asyncio-task.html#asyncio.Task) для совместимости. В этом случае тип результата является подклассом [`Task`](https://python-all.ru/3.11/library/asyncio-task.html#asyncio.Task).238239Если аргумент *name* указан и не равен `None`, он устанавливается как имя задачи с помощью [`Task.set_name()`](https://python-all.ru/3.11/library/asyncio-task.html#asyncio.Task.set_name).240241Необязательный именованный аргумент *context* позволяет указать пользовательский [`contextvars.Context`](https://python-all.ru/3.11/library/contextvars.html#contextvars.Context) для выполнения *coro*. Копия текущего контекста создаётся, если *context* не передан.242243Изменено в версии 3.8: Добавлен параметр *name*.244245Изменено в версии 3.11: Добавлен параметр *context*.246247#### `loop.set_task_factory(factory)`248249Устанавливает фабрику задач, которая будет использоваться [`loop.create_task()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_task).250251Если *factory* равен `None`, будет установлена фабрика задач по умолчанию. В противном случае *factory* должен быть *вызываемым объектом* с сигнатурой, соответствующей `(loop, coro, context=None)`, где *loop* – это ссылка на активный цикл событий, а *coro* – объект корутины. Такой вызываемый объект должен возвращать объект, совместимый с [`asyncio.Future`](https://python-all.ru/3.11/library/asyncio-future.html#asyncio.Future).252253#### `loop.get_task_factory()`254255Возвращает фабрику задач или `None`, если используется стандартная.256257### [Открытие сетевых соединений](https://python-all.ru/3.11/library/asyncio-eventloop.html#id5)258259#### `coroutine loop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, happy_eyeballs_delay=None, interleave=None)`260261Открывает потоковое транспортное соединение по заданному адресу, указанному в *host* и *port*.262263Семейство сокетов может быть [`AF_INET`](https://python-all.ru/3.11/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.11/library/socket.html#socket.AF_INET6) в зависимости от *host* (или аргумента *family*, если он передан).264265Тип сокета будет [`SOCK_STREAM`](https://python-all.ru/3.11/library/socket.html#socket.SOCK_STREAM).266267*protocol\_factory* должен быть вызываемым объектом, возвращающим реализацию [протокола asyncio](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-protocol).268269Этот метод попытается установить соединение в фоновом режиме. При успехе он возвращает пару `(transport, protocol)`.270271Хронологическая последовательность выполняемой операции следующая:2722731. Соединение устанавливается, и для него создаётся [транспорт](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-transport) .2742. *protocol\_factory* вызывается без аргументов и должен вернуть экземпляр [протокола](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-protocol).2753. Экземпляр протокола связывается с транспортом вызовом его метода [`connection_made()`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.BaseProtocol.connection_made).2764. При успехе возвращается кортеж `(transport, protocol)`.277278Созданный транспорт представляет собой двунаправленный поток данных, зависящий от реализации.279280Остальные аргументы:281282- *ssl*: если указан и не равен false, создаётся транспорт SSL/TLS (по умолчанию создаётся обычный TCP-транспорт). Если *ssl* является объектом [`ssl.SSLContext`](https://python-all.ru/3.11/library/ssl.html#ssl.SSLContext), этот контекст используется для создания транспорта; если *ssl* равно [`True`](https://python-all.ru/3.11/library/constants.html#True), используется контекст по умолчанию, возвращаемый из [`ssl.create_default_context()`](https://python-all.ru/3.11/library/ssl.html#ssl.create_default_context).283284 > **См. также**285 >286 > [Вопросы безопасности SSL/TLS](https://python-all.ru/3.11/library/ssl.html#ssl-security)287- *server\_hostname* задаёт или переопределяет имя хоста, с которым будет сверяться сертификат целевого сервера. Следует передавать только если *ssl* не равен `None`. По умолчанию используется значение аргумента *host*. Если *host* пуст, значения по умолчанию нет, и необходимо передать значение для *server\_hostname*. Если *server\_hostname* – пустая строка, сопоставление имён хостов отключается (что представляет серьёзную угрозу безопасности, допуская атаки «человек посередине»).288- *family*, *proto*, *flags* – необязательные семейство адресов, протокол и флаги, которые передаются в getaddrinfo() для разрешения *host*. Если заданы, все они должны быть целыми числами из соответствующих констант модуля [`socket`](https://python-all.ru/3.11/library/socket.html#module-socket).289- *happy\_eyeballs\_delay*, если задан, включает Happy Eyeballs для этого соединения. Должен быть числом с плавающей запятой, представляющим время в секундах ожидания завершения попытки соединения перед запуском следующей параллельной попытки. Это «задержка попытки соединения», как определено в [**RFC 8305**](https://python-all.ru/3.11/library/asyncio-eventloop.html). Разумное значение по умолчанию, рекомендуемое RFC, – `0.25` (250 миллисекунд).290- *interleave* управляет переупорядочением адресов, когда имя хоста разрешается в несколько IP-адресов. Если `0` или не указан, переупорядочение не выполняется, и адреса перебираются в порядке, возвращаемом [`getaddrinfo()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.getaddrinfo). Если указано положительное целое число, адреса перемежаются по семейству адресов, и заданное число интерпретируется как «количество первого семейства адресов», как определено в [**RFC 8305**](https://python-all.ru/3.11/library/asyncio-eventloop.html). Значение по умолчанию – `0`, если *happy\_eyeballs\_delay* не указан, и `1`, если указан.291- *sock*, если задан, должен быть существующим, уже подключённым объектом [`socket.socket`](https://python-all.ru/3.11/library/socket.html#socket.socket), который будет использоваться транспортом. Если задан *sock*, не должны указываться ни *host*, *port*, *family*, *proto*, *flags*, *happy\_eyeballs\_delay*, *interleave*, ни *local\_addr*.292293 > **Примечание**294 >295 > Аргумент *sock* передаёт владение сокетом созданному транспорту. Чтобы закрыть сокет, вызовите метод [`close()`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.BaseTransport.close) транспорта.296- *local\_addr*, если задан, представляет собой кортеж `(local_host, local_port)`, используемый для локальной привязки сокета. *local\_host* и *local\_port* разрешаются с помощью `getaddrinfo()`, аналогично *host* и *port*.297- *ssl\_handshake\_timeout* (для TLS-соединения) – время в секундах ожидания завершения рукопожатия TLS перед разрывом соединения. `60.0` секунд, если `None` (по умолчанию).298- *ssl\_shutdown\_timeout* – время в секундах ожидания завершения закрытия SSL перед разрывом соединения. `30.0` секунд, если `None` (по умолчанию).299300Изменено в версии 3.5: Добавлена поддержка SSL/TLS в [`ProactorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.ProactorEventLoop).301302Изменено в версии 3.6: Параметр сокета [socket.TCP\_NODELAY](https://python-all.ru/3.11/library/socket.html#socket-unix-constants) теперь устанавливается по умолчанию для всех TCP-соединений.303304Изменено в версии 3.7: Добавлен параметр *ssl\_handshake\_timeout*.305306Изменено в версии 3.8: Добавлены параметры *happy\_eyeballs\_delay* и *interleave*.307308Алгоритм Happy Eyeballs: успех с двухстековыми хостами. Когда IPv4-путь и протокол сервера работают, а IPv6-путь и протокол сервера не работают, двухстековое клиентское приложение испытывает значительную задержку соединения по сравнению с клиентом, использующим только IPv4. Это нежелательно, так как ухудшает пользовательский опыт для двухстекового клиента. В этом документе указаны требования к алгоритмам, уменьшающим эту заметную пользователю задержку, и приводится сам алгоритм.309310Дополнительная информация: [https://datatracker.ietf.org/doc/html/rfc6555](https://python-all.ru/3.11/library/asyncio-eventloop.html)311312Изменено в версии 3.11: Добавлен параметр *ssl\_shutdown\_timeout*.313314> **См. также**315>316> Функция [`open_connection()`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.open_connection) является высокоуровневой альтернативой API. Она возвращает пару ([`StreamReader`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.StreamReader), [`StreamWriter`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.StreamWriter)), которую можно использовать непосредственно в коде с async/await.317318#### `coroutine loop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_port=None, allow_broadcast=None, sock=None)`319320Создать датаграммное соединение.321322Семейство сокетов может быть одним из [`AF_INET`](https://python-all.ru/3.11/library/socket.html#socket.AF_INET), [`AF_INET6`](https://python-all.ru/3.11/library/socket.html#socket.AF_INET6) или [`AF_UNIX`](https://python-all.ru/3.11/library/socket.html#socket.AF_UNIX), в зависимости от *host* (или аргумента *family*, если он задан).323324Тип сокета будет [`SOCK_DGRAM`](https://python-all.ru/3.11/library/socket.html#socket.SOCK_DGRAM).325326*protocol\_factory* должен быть вызываемым объектом, возвращающим реализацию [протокола](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-protocol).327328При успехе возвращается кортеж из `(transport, protocol)`.329330Остальные аргументы:331332- *local\_addr*, если задан, представляет собой кортеж `(local_host, local_port)`, используемый для локальной привязки сокета. *local\_host* и *local\_port* разрешаются с помощью [`getaddrinfo()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.getaddrinfo).333- *remote\_addr*, если задан, представляет собой кортеж `(remote_host, remote_port)`, используемый для подключения сокета к удалённому адресу. *remote\_host* и *remote\_port* разрешаются с помощью [`getaddrinfo()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.getaddrinfo).334- *family*, *proto*, *flags* – необязательные семейство адресов, протокол и флаги, передаваемые в [`getaddrinfo()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.getaddrinfo) для разрешения *host*. Если заданы, все они должны быть целыми числами из соответствующих констант модуля [`socket`](https://python-all.ru/3.11/library/socket.html#module-socket).335- *reuse\_port* указывает ядру разрешить привязку данной конечной точки к тому же порту, к которому привязаны другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Этот параметр не поддерживается в Windows и некоторых Unix-системах. Если константа [socket.SO\_REUSEPORT](https://python-all.ru/3.11/library/socket.html#socket-unix-constants) не определена, то эта возможность не поддерживается.336- *allow\_broadcast* указывает ядру разрешить этой конечной точке отправлять сообщения на широковещательный адрес.337- *sock* может быть указан необязательно, чтобы использовать уже существующий, подключённый объект [`socket.socket`](https://python-all.ru/3.11/library/socket.html#socket.socket) для транспорта. Если указан, *local\_addr* и *remote\_addr* должны быть опущены (должны быть [`None`](https://python-all.ru/3.11/library/constants.html#None)).338339 > **Примечание**340 >341 > Аргумент *sock* передаёт владение сокетом созданному транспорту. Чтобы закрыть сокет, вызовите метод [`close()`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.BaseTransport.close) транспорта.342343См. примеры [протокол UDP-клиента эхо](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-udp-echo-client-protocol) и [протокол UDP-сервера эхо](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-udp-echo-server-protocol).344345Изменено в версии 3.4.4: Добавлены параметры *family*, *proto*, *flags*, *reuse\_address*, *reuse\_port*, *allow\_broadcast* и *sock*.346347Изменено в версии 3.8: Добавлена поддержка Windows.348349Изменено в версии 3.8.1: Параметр *reuse\_address* больше не поддерживается, поскольку использование [socket.SO\_REUSEADDR](https://python-all.ru/3.11/library/socket.html#socket-unix-constants) представляет существенную угрозу безопасности для UDP. Явная передача `reuse_address=True` приведёт к возбуждению исключения.350351Когда несколько процессов с разными UID назначают сокеты одному и тому же адресу UDP-сокета с помощью `SO_REUSEADDR`, входящие пакеты могут случайным образом распределяться между сокетами.352353На поддерживаемых платформах *reuse\_port* может использоваться как замена аналогичной функциональности. При *reuse\_port* вместо этого применяется [socket.SO\_REUSEPORT](https://python-all.ru/3.11/library/socket.html#socket-unix-constants), который специально предотвращает назначение сокетов одному и тому же адресу сокета процессами с разными UID.354355Изменено в версии 3.11: Параметр *reuse\_address*, отключённый начиная с Python 3.8.1, 3.7.6 и 3.6.10, был полностью удалён.356357#### `coroutine loop.create_unix_connection(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)`358359Создать Unix-соединение.360361Семейство сокетов будет [`AF_UNIX`](https://python-all.ru/3.11/library/socket.html#socket.AF_UNIX); тип сокета будет [`SOCK_STREAM`](https://python-all.ru/3.11/library/socket.html#socket.SOCK_STREAM).362363При успехе возвращается кортеж из `(transport, protocol)`.364365*path* – это имя доменного сокета Unix, обязательный параметр, если не указан параметр *sock*. Поддерживаются абстрактные сокеты Unix, пути [`str`](https://python-all.ru/3.11/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.11/library/stdtypes.html#bytes) и [`Path`](https://python-all.ru/3.11/library/pathlib.html#pathlib.Path).366367Информацию об аргументах этого метода см. в документации метода [`loop.create_connection()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_connection).368369[Доступность](https://python-all.ru/3.11/library/intro.html#availability): Unix.370371Изменено в версии 3.7: Добавлен параметр *ssl\_handshake\_timeout*. Параметр *path* теперь может быть [объектом, подобным пути](https://python-all.ru/3.11/glossary.html#term-path-like-object).372373Изменено в версии 3.11: Добавлен параметр *ssl\_shutdown\_timeout*.374375### [Создание сетевых серверов](https://python-all.ru/3.11/library/asyncio-eventloop.html#id6)376377#### `coroutine loop.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, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True)`378379Создаёт TCP-сервер (тип сокета [`SOCK_STREAM`](https://python-all.ru/3.11/library/socket.html#socket.SOCK_STREAM)), прослушивающий порт на адресе *хоста*.380381Возвращает объект [`Server`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Server).382383Аргументы:384385- *protocol\_factory* должен быть вызываемым объектом, возвращающим реализацию [протокола](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-protocol).386- Параметр *host* может принимать значения нескольких типов, которые определяют, где будет слушать сервер:387388 - Если *host* – строка, TCP-сервер привязывается к одному сетевому интерфейсу, указанному в *host*.389 - Если *host* – последовательность строк, TCP-сервер привязывается ко всем сетевым интерфейсам, указанным в этой последовательности.390 - Если *host* – пустая строка или `None`, подразумеваются все интерфейсы, и будет возвращён список из нескольких сокетов (скорее всего, один для IPv4 и один для IPv6).391- Параметр *port* можно задать, чтобы указать, какой порт должен слушать сервер. Если `0` или `None` (по умолчанию), будет выбран случайный свободный порт (обратите внимание: если *host* разрешается в несколько сетевых интерфейсов, для каждого интерфейса будет выбран разный случайный порт).392- *family* может быть установлен в [`socket.AF_INET`](https://python-all.ru/3.11/library/socket.html#socket.AF_INET) или [`AF_INET6`](https://python-all.ru/3.11/library/socket.html#socket.AF_INET6), чтобы принудительно использовать IPv4 или IPv6. Если не задан, *family* будет определён по имени хоста (по умолчанию [`AF_UNSPEC`](https://python-all.ru/3.11/library/socket.html#socket.AF_UNSPEC)).393- *flags* – битовая маска для [`getaddrinfo()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.getaddrinfo).394- *sock* может быть указан опционально, чтобы использовать уже существующий объект сокета. Если он указан, *host* и *port* не должны быть заданы.395396 > **Примечание**397 >398 > Аргумент *sock* передаёт владение сокетом созданному серверу. Чтобы закрыть сокет, вызовите метод сервера [`close()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Server.close).399- *backlog* – максимальное количество соединений в очереди, передаваемое в [`listen()`](https://python-all.ru/3.11/library/socket.html#socket.socket.listen) (по умолчанию 100).400- *ssl* может быть установлен в экземпляр [`SSLContext`](https://python-all.ru/3.11/library/ssl.html#ssl.SSLContext) для включения TLS для принимаемых соединений.401- *reuse\_address* указывает ядру повторно использовать локальный сокет в состоянии `TIME_WAIT`, не дожидаясь истечения его естественного тайм-аута. Если не указан, автоматически устанавливается в `True` на Unix.402- *reuse\_port* указывает ядру разрешить привязку этой конечной точки к тому же порту, к которому привязаны другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Эта опция не поддерживается в Windows.403- *ssl\_handshake\_timeout* (для TLS-сервера) – время ожидания в секундах завершения TLS-рукопожатия перед разрывом соединения. `60.0` секунд, если `None` (по умолчанию).404- *ssl\_shutdown\_timeout* – время в секундах ожидания завершения закрытия SSL перед разрывом соединения. `30.0` секунд, если `None` (по умолчанию).405- *start\_serving*, установленный в `True` (по умолчанию), заставляет созданный сервер немедленно начать принимать соединения. Если установлен в `False`, пользователь должен дождаться [`Server.start_serving()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Server.start_serving) или [`Server.serve_forever()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Server.serve_forever), чтобы сервер начал принимать соединения.406407Изменено в версии 3.5: Добавлена поддержка SSL/TLS в [`ProactorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.ProactorEventLoop).408409Изменено в версии 3.5.1: Параметр *host* может быть последовательностью строк.410411Изменено в версии 3.6: Добавлены параметры *ssl\_handshake\_timeout* и *start\_serving*. Опция сокета [socket.TCP\_NODELAY](https://python-all.ru/3.11/library/socket.html#socket-unix-constants) по умолчанию установлена для всех TCP-соединений.412413Изменено в версии 3.11: Добавлен параметр *ssl\_shutdown\_timeout*.414415> **См. также**416>417> Функция [`start_server()`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.start_server) – это API более высокого уровня, который возвращает пару [`StreamReader`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.StreamReader) и [`StreamWriter`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.StreamWriter), которые можно использовать в коде с async/await.418419#### `coroutine loop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True)`420421Аналогично [`loop.create_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_server), но работает с семейством сокетов [`AF_UNIX`](https://python-all.ru/3.11/library/socket.html#socket.AF_UNIX).422423*path* – имя сокета домена Unix и является обязательным, если не передан аргумент *sock*. Поддерживаются абстрактные сокеты Unix, пути [`str`](https://python-all.ru/3.11/library/stdtypes.html#str), [`bytes`](https://python-all.ru/3.11/library/stdtypes.html#bytes) и [`Path`](https://python-all.ru/3.11/library/pathlib.html#pathlib.Path).424425Информацию об аргументах этого метода см. в документации метода [`loop.create_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_server).426427[Доступность](https://python-all.ru/3.11/library/intro.html#availability): Unix.428429Изменено в версии 3.7: Добавлены параметры *ssl\_handshake\_timeout* и *start\_serving*. Параметр *path* теперь может быть объектом [`Path`](https://python-all.ru/3.11/library/pathlib.html#pathlib.Path).430431Изменено в версии 3.11: Добавлен параметр *ssl\_shutdown\_timeout*.432433#### `coroutine loop.connect_accepted_socket(protocol_factory, sock, *, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)`434435Оборачивает уже принятое соединение в пару транспорт/протокол.436437Этот метод могут использовать серверы, которые принимают соединения вне asyncio, но используют asyncio для их обработки.438439Параметры:440441- *protocol\_factory* должен быть вызываемым объектом, возвращающим реализацию [протокола](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-protocol).442- *sock* – это существующий объект сокета, возвращённый из [`socket.accept`](https://python-all.ru/3.11/library/socket.html#socket.socket.accept).443444 > **Примечание**445 >446 > Аргумент *sock* передаёт владение сокетом созданному транспорту. Чтобы закрыть сокет, вызовите метод [`close()`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.BaseTransport.close) транспорта.447- *ssl* можно установить в [`SSLContext`](https://python-all.ru/3.11/library/ssl.html#ssl.SSLContext), чтобы включить SSL для принятых соединений.448- *ssl\_handshake\_timeout* (для SSL-соединения) – время в секундах ожидания завершения SSL-рукопожатия перед разрывом соединения. `60.0` секунд, если `None` (по умолчанию).449- *ssl\_shutdown\_timeout* – время в секундах ожидания завершения закрытия SSL перед разрывом соединения. `30.0` секунд, если `None` (по умолчанию).450451Возвращает пару `(transport, protocol)`.452453Новое в версии 3.5.3.454455Изменено в версии 3.7: Добавлен параметр *ssl\_handshake\_timeout*.456457Изменено в версии 3.11: Добавлен параметр *ssl\_shutdown\_timeout*.458459### [Передача файлов](https://python-all.ru/3.11/library/asyncio-eventloop.html#id7)460461#### `coroutine loop.sendfile(transport, file, offset=0, count=None, *, fallback=True)`462463Отправляет *файл* через *транспорт*. Возвращает общее количество отправленных байтов.464465Метод использует высокопроизводительный [`os.sendfile()`](https://python-all.ru/3.11/library/os.html#os.sendfile), если доступен.466467*file* должен быть обычным файловым объектом, открытым в бинарном режиме.468469*offset* указывает, с какого места начинать чтение файла. Если задан, *count* – это общее количество байтов для передачи, в отличие от отправки файла до достижения EOF. Позиция в файле всегда обновляется, даже если этот метод вызывает ошибку, а [`file.tell()`](https://python-all.ru/3.11/library/io.html#io.IOBase.tell) можно использовать для получения фактического количества отправленных байтов.470471*fallback*, установленный в `True`, заставляет asyncio вручную читать и отправлять файл, если платформа не поддерживает системный вызов sendfile (например, Windows или SSL-сокет в Unix).472473Вызывает [`SendfileNotAvailableError`](https://python-all.ru/3.11/library/asyncio-exceptions.html#asyncio.SendfileNotAvailableError), если система не поддерживает системный вызов *sendfile*, а *fallback* равен `False`.474475Добавлено в версии 3.7.476477### [Обновление TLS](https://python-all.ru/3.11/library/asyncio-eventloop.html#id8)478479#### `coroutine loop.start_tls(transport, protocol, sslcontext, *, server_side=False, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None)`480481Обновляет существующее соединение на основе транспорта до TLS.482483Создаёт экземпляр кодировщика/декодировщика TLS и вставляет его между *транспортом* и *протоколом*. Кодировщик/декодировщик реализует как протокол, обращённый к *транспорту*, так и транспорт, обращённый к *протоколу*.484485Возвращает созданный экземпляр с двумя интерфейсами. После *await* *протокол* должен прекратить использовать исходный *транспорт* и общаться только с возвращённым объектом, поскольку кодировщик кэширует данные со стороны *протокола* и периодически обменивается дополнительными пакетами сеанса TLS с *транспортом*.486487В некоторых ситуациях (например, когда переданный транспорт уже закрывается) это может вернуть `None`.488489Параметры:490491- *транспорт* и *протокол* – экземпляры, возвращаемые методами наподобие [`create_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_server) и [`create_connection()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_connection).492- *sslcontext*: настроенный экземпляр [`SSLContext`](https://python-all.ru/3.11/library/ssl.html#ssl.SSLContext).493- *server\_side* передавайте `True` при обновлении серверного соединения (например, созданного [`create_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_server)).494- *server\_hostname*: задаёт или переопределяет имя узла, с которым будет сверяться сертификат целевого сервера.495- *ssl\_handshake\_timeout* – время в секундах, в течение которого ожидается завершение TLS-рукопожатия перед разрывом соединения (для TLS-соединений). `60.0` секунд, если `None` (по умолчанию).496- *ssl\_shutdown\_timeout* – время в секундах ожидания завершения закрытия SSL перед разрывом соединения. `30.0` секунд, если `None` (по умолчанию).497498Добавлено в версии 3.7.499500Изменено в версии 3.11: Добавлен параметр *ssl\_shutdown\_timeout*.501502### [Наблюдение за файловыми дескрипторами](https://python-all.ru/3.11/library/asyncio-eventloop.html#id9)503504#### `loop.add_reader(fd, callback, *args)`505506Начинает наблюдение за файловым дескриптором *fd* на готовность к чтению и вызывает *колбэк* с указанными аргументами, как только *fd* станет доступен для чтения.507508#### `loop.remove_reader(fd)`509510Прекращает наблюдение за файловым дескриптором *fd* на готовность к чтению. Возвращает `True`, если *fd* ранее наблюдался на чтение.511512#### `loop.add_writer(fd, callback, *args)`513514Начинает отслеживать готовность файлового дескриптора *fd* к записи и вызывает *колбэк* с указанными аргументами, как только *fd* становится доступным для записи.515516Используйте [`functools.partial()`](https://python-all.ru/3.11/library/functools.html#functools.partial) [для передачи именованных аргументов](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio-pass-keywords) в *колбэк*.517518#### `loop.remove_writer(fd)`519520Прекращает наблюдение за файловым дескриптором *fd* на готовность к записи. Возвращает `True`, если *fd* ранее наблюдался на запись.521522См. также раздел [Поддержка платформ](https://python-all.ru/3.11/library/asyncio-platforms.html#asyncio-platform-support) о некоторых ограничениях этих методов.523524### [Работа с объектами сокетов напрямую](https://python-all.ru/3.11/library/asyncio-eventloop.html#id10)525526В целом реализации протоколов, использующие API на основе транспорта, такие как [`loop.create_connection()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_connection) и [`loop.create_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_server), работают быстрее реализаций, работающих напрямую с сокетами. Однако есть случаи, когда производительность не критична, и работать напрямую с объектами [`socket`](https://python-all.ru/3.11/library/socket.html#socket.socket) удобнее.527528#### `coroutine loop.sock_recv(sock, nbytes)`529530Получает до *nbytes* байт из *sock*. Асинхронная версия [`socket.recv()`](https://python-all.ru/3.11/library/socket.html#socket.socket.recv).531532Возвращает полученные данные в виде объекта bytes.533534*sock* должен быть неблокирующим сокетом.535536Изменено в версии 3.7: Хотя этот метод всегда документировался как корутинный, до Python 3.7 он возвращал [`Future`](https://python-all.ru/3.11/library/asyncio-future.html#asyncio.Future). Начиная с Python 3.7 это `async def` метод.537538#### `coroutine loop.sock_recv_into(sock, buf)`539540Получает данные из *sock* в буфер *buf*. По аналогии с блокирующим методом [`socket.recv_into()`](https://python-all.ru/3.11/library/socket.html#socket.socket.recv_into).541542Возвращает количество байт, записанных в буфер.543544*sock* должен быть неблокирующим сокетом.545546Добавлено в версии 3.7.547548#### `coroutine loop.sock_recvfrom(sock, bufsize)`549550Получает дейтаграмму размером до *bufsize* из *sock*. Асинхронная версия [`socket.recvfrom()`](https://python-all.ru/3.11/library/socket.html#socket.socket.recvfrom).551552Возвращает кортеж (полученные данные, удалённый адрес).553554*sock* должен быть неблокирующим сокетом.555556Новое в версии 3.11.557558#### `coroutine loop.sock_recvfrom_into(sock, buf, nbytes=0)`559560Получает дейтаграмму размером до *nbytes* из *sock* в *buf*. Асинхронная версия [`socket.recvfrom_into()`](https://python-all.ru/3.11/library/socket.html#socket.socket.recvfrom_into).561562Возвращает кортеж (количество полученных байт, удалённый адрес).563564*sock* должен быть неблокирующим сокетом.565566Новое в версии 3.11.567568#### `coroutine loop.sock_sendall(sock, data)`569570Отправляет *data* в сокет *sock*. Асинхронная версия [`socket.sendall()`](https://python-all.ru/3.11/library/socket.html#socket.socket.sendall).571572Этот метод продолжает отправку в сокет, пока не будут отправлены все данные из *data* или не возникнет ошибка. В случае успеха возвращается `None`. При ошибке вызывается исключение. Кроме того, невозможно определить, какой объём данных (если он был) был успешно обработан принимающей стороной соединения.573574*sock* должен быть неблокирующим сокетом.575576Изменено в версии 3.7: Хотя этот метод всегда документировался как корутинный метод, до Python 3.7 он возвращал [`Future`](https://python-all.ru/3.11/library/asyncio-future.html#asyncio.Future). Начиная с Python 3.7, это `async def` метод.577578#### `coroutine loop.sock_sendto(sock, data, address)`579580Отправляет дейтаграмму из *sock* на *address*. Асинхронная версия [`socket.sendto()`](https://python-all.ru/3.11/library/socket.html#socket.socket.sendto).581582Возвращает количество отправленных байт.583584*sock* должен быть неблокирующим сокетом.585586Новое в версии 3.11.587588#### `coroutine loop.sock_connect(sock, address)`589590Подключает *sock* к удалённому сокету по адресу *address*.591592Асинхронная версия [`socket.connect()`](https://python-all.ru/3.11/library/socket.html#socket.socket.connect).593594*sock* должен быть неблокирующим сокетом.595596Изменено в версии 3.5.2: `address` больше не требует разрешения. `sock_connect` попытается проверить, разрешён ли уже *address*, вызвав [`socket.inet_pton()`](https://python-all.ru/3.11/library/socket.html#socket.inet_pton). Если нет, [`loop.getaddrinfo()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.getaddrinfo) будет использован для разрешения *address*.597598> **См. также**599>600> [`loop.create_connection()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_connection) и [`asyncio.open_connection()`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.open_connection).601602#### `coroutine loop.sock_accept(sock)`603604Принимает соединение. Смоделирован по аналогии с блокирующим методом [`socket.accept()`](https://python-all.ru/3.11/library/socket.html#socket.socket.accept).605606Сокет должен быть привязан к адресу и ожидать подключения. Возвращаемое значение – пара `(conn, address)`, где *conn* – это *новый* объект сокета, пригодный для отправки и получения данных по соединению, а *address* – адрес, привязанный к сокету на другом конце соединения.607608*sock* должен быть неблокирующим сокетом.609610Изменено в версии 3.7: Хотя этот метод всегда документировался как корутинный метод, до Python 3.7 он возвращал [`Future`](https://python-all.ru/3.11/library/asyncio-future.html#asyncio.Future). Начиная с Python 3.7, это `async def` метод.611612> **См. также**613>614> [`loop.create_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_server) и [`start_server()`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.start_server).615616#### `coroutine loop.sock_sendfile(sock, file, offset=0, count=None, *, fallback=True)`617618Отправляет файл с использованием высокопроизводительного [`os.sendfile`](https://python-all.ru/3.11/library/os.html#os.sendfile), если возможно. Возвращает общее количество отправленных байт.619620Асинхронная версия [`socket.sendfile()`](https://python-all.ru/3.11/library/socket.html#socket.socket.sendfile).621622*sock* должен быть неблокирующим [`socket.SOCK_STREAM`](https://python-all.ru/3.11/library/socket.html#socket.SOCK_STREAM) [`socket`](https://python-all.ru/3.11/library/socket.html#socket.socket).623624*file* должен быть обычным файловым объектом, открытым в бинарном режиме.625626*offset* указывает, с какого места начинать чтение файла. Если задан, *count* – это общее количество байтов для передачи, в отличие от отправки файла до достижения EOF. Позиция в файле всегда обновляется, даже если этот метод вызывает ошибку, а [`file.tell()`](https://python-all.ru/3.11/library/io.html#io.IOBase.tell) можно использовать для получения фактического количества отправленных байтов.627628*fallback*, если установлено в `True`, заставляет asyncio вручную читать и отправлять файл, когда платформа не поддерживает системный вызов sendfile (например, Windows или SSL-сокет в Unix).629630Вызывает [`SendfileNotAvailableError`](https://python-all.ru/3.11/library/asyncio-exceptions.html#asyncio.SendfileNotAvailableError), если система не поддерживает системный вызов *sendfile* и *fallback* равен `False`.631632*sock* должен быть неблокирующим сокетом.633634Добавлено в версии 3.7.635636### [DNS](https://python-all.ru/3.11/library/asyncio-eventloop.html#id11)637638#### `coroutine loop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0)`639640Асинхронная версия [`socket.getaddrinfo()`](https://python-all.ru/3.11/library/socket.html#socket.getaddrinfo).641642#### `coroutine loop.getnameinfo(sockaddr, flags=0)`643644Асинхронная версия [`socket.getnameinfo()`](https://python-all.ru/3.11/library/socket.html#socket.getnameinfo).645646Изменено в версии 3.7: Оба метода, *getaddrinfo* и *getnameinfo*, всегда документировались как возвращающие корутину, но до Python 3.7 на самом деле возвращали объекты [`asyncio.Future`](https://python-all.ru/3.11/library/asyncio-future.html#asyncio.Future). Начиная с Python 3.7 оба метода являются корутинами.647648### [Работа с каналами](https://python-all.ru/3.11/library/asyncio-eventloop.html#id12)649650#### `coroutine loop.connect_read_pipe(protocol_factory, pipe)`651652Регистрирует читающий конец канала *pipe* в цикле событий.653654*protocol\_factory* должен быть вызываемым объектом, возвращающим реализацию [протокола asyncio](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-protocol).655656*pipe* – это [объект, подобный файлу](https://python-all.ru/3.11/glossary.html#term-file-object).657658Возвращает пару `(transport, protocol)`, где *транспорт* поддерживает интерфейс [`ReadTransport`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.ReadTransport), а *протокол* – объект, созданный фабрикой *protocol\_factory*.659660При [`SelectorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.SelectorEventLoop) цикле событий канал *pipe* переводится в неблокирующий режим.661662#### `coroutine loop.connect_write_pipe(protocol_factory, pipe)`663664Регистрирует записывающий конец канала *pipe* в цикле событий.665666*protocol\_factory* должен быть вызываемым объектом, возвращающим реализацию [протокола asyncio](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-protocol).667668*pipe* – это [объект, подобный файлу](https://python-all.ru/3.11/glossary.html#term-file-object).669670Возвращает пару `(transport, protocol)`, где *транспорт* поддерживает интерфейс [`WriteTransport`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.WriteTransport), а *протокол* – объект, созданный фабрикой *protocol\_factory*.671672При [`SelectorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.SelectorEventLoop) цикле событий канал *pipe* переводится в неблокирующий режим.673674> **Примечание**675>676> [`SelectorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.SelectorEventLoop) не поддерживает указанные выше методы в Windows. Используйте [`ProactorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.ProactorEventLoop) вместо них в Windows.677678> **См. также**679>680> Методы [`loop.subprocess_exec()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec) и [`loop.subprocess_shell()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.subprocess_shell).681682### [Сигналы Unix](https://python-all.ru/3.11/library/asyncio-eventloop.html#id13)683684#### `loop.add_signal_handler(signum, callback, *args)`685686Устанавливает *колбэк* в качестве обработчика сигнала *signum*.687688Колбэк будет вызван *loop* вместе с другими поставленными в очередь колбэками и готовыми к запуску корутинами этого цикла событий. В отличие от обработчиков сигналов, зарегистрированных с помощью [`signal.signal()`](https://python-all.ru/3.11/library/signal.html#signal.signal), колбэк, зарегистрированный этой функцией, может взаимодействовать с циклом событий.689690Вызывает [`ValueError`](https://python-all.ru/3.11/library/exceptions.html#ValueError), если номер сигнала недопустим или его невозможно перехватить. Вызывает [`RuntimeError`](https://python-all.ru/3.11/library/exceptions.html#RuntimeError), если возникла проблема при установке обработчика.691692Используйте [`functools.partial()`](https://python-all.ru/3.11/library/functools.html#functools.partial) [для передачи именованных аргументов](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio-pass-keywords) в *колбэк*.693694Как и [`signal.signal()`](https://python-all.ru/3.11/library/signal.html#signal.signal), эта функция должна вызываться в главном потоке.695696#### `loop.remove_signal_handler(sig)`697698Удаляет обработчик сигнала *sig*.699700Возвращает `True`, если обработчик сигнала был удалён, или `False`, если для указанного сигнала обработчик не был установлен.701702[Доступность](https://python-all.ru/3.11/library/intro.html#availability): Unix.703704> **См. также**705>706> Модуль [`signal`](https://python-all.ru/3.11/library/signal.html#module-signal).707708### [Выполнение кода в пулах потоков или процессов](https://python-all.ru/3.11/library/asyncio-eventloop.html#id14)709710#### `awaitable loop.run_in_executor(executor, func, *args)`711712Планирует вызов *func* в указанном исполнителе.713714Аргумент *исполнитель* должен быть экземпляром [`concurrent.futures.Executor`](https://python-all.ru/3.11/library/concurrent.futures.html#concurrent.futures.Executor) Исполнитель по умолчанию используется, если *исполнитель* равен `None`.715716Пример:717718```python719import asyncio720import concurrent.futures721722def blocking_io():723 # Файловые операции (например, логирование) могут блокировать цикл событий: выполняйте их в пуле потоков.724 # цикл событий: выполняйте их в пуле потоков.725 with open('/dev/urandom', 'rb') as f:726 return f.read(100)727728def cpu_bound():729 # CPU-ёмкие операции заблокируют цикл событий:730 # в целом предпочтительнее выполнять их в731 # пуле процессов.732 return sum(i * i for i in range(10 ** 7))733734async def main():735 loop = asyncio.get_running_loop()736737 ## Варианты:738739 # 1. Запуск в исполнителе цикла по умолчанию:740 result = await loop.run_in_executor(741 None, blocking_io)742 print('default thread pool', result)743744 # 2. Запуск в пользовательском пуле потоков:745 with concurrent.futures.ThreadPoolExecutor() as pool:746 result = await loop.run_in_executor(747 pool, blocking_io)748 print('custom thread pool', result)749750 # 3. Запуск в пользовательском пуле процессов:751 with concurrent.futures.ProcessPoolExecutor() as pool:752 result = await loop.run_in_executor(753 pool, cpu_bound)754 print('custom process pool', result)755756if __name__ == '__main__':757 asyncio.run(main())758```759760Обратите внимание, что защита точки входа (`if __name__ == '__main__'`) требуется для варианта 3 из-за особенностей [`multiprocessing`](https://python-all.ru/3.11/library/multiprocessing.html#module-multiprocessing), используемого в [`ProcessPoolExecutor`](https://python-all.ru/3.11/library/concurrent.futures.html#concurrent.futures.ProcessPoolExecutor). См. [Безопасный импорт главного модуля](https://python-all.ru/3.11/library/multiprocessing.html#multiprocessing-safe-main-import).761762Этот метод возвращает объект [`asyncio.Future`](https://python-all.ru/3.11/library/asyncio-future.html#asyncio.Future).763764Используйте [`functools.partial()`](https://python-all.ru/3.11/library/functools.html#functools.partial) [для передачи именованных аргументов](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio-pass-keywords) в *func*.765766Изменено в версии 3.5.3: [`loop.run_in_executor()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.run_in_executor) больше не настраивает `max_workers` создаваемого исполнителя пула потоков, оставляя настройку по умолчанию самому исполнителю пула потоков ([`ThreadPoolExecutor`](https://python-all.ru/3.11/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)).767768#### `loop.set_default_executor(executor)`769770Устанавливает *исполнитель* в качестве исполнителя по умолчанию, используемого [`run_in_executor()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.run_in_executor). *исполнитель* должен быть экземпляром [`ThreadPoolExecutor`](https://python-all.ru/3.11/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor).771772Изменено в версии 3.11: *исполнитель* должен быть экземпляром [`ThreadPoolExecutor`](https://python-all.ru/3.11/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor).773774### [API обработки ошибок](https://python-all.ru/3.11/library/asyncio-eventloop.html#id15)775776Позволяет настраивать обработку исключений в цикле событий.777778#### `loop.set_exception_handler(handler)`779780Устанавливает *handler* в качестве нового обработчика исключений цикла событий.781782Если *handler* равен `None`, будет установлен обработчик исключений по умолчанию. В противном случае *handler* должен быть вызываемым объектом с сигнатурой, соответствующей `(loop, context)`, где `loop` – это ссылка на активный цикл событий, а `context` – это объект `dict`, содержащий сведения об исключении (см. документацию [`call_exception_handler()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_exception_handler) для подробностей о контексте).783784#### `loop.get_exception_handler()`785786Возвращает текущий обработчик исключений или `None`, если не был установлен пользовательский обработчик.787788Новое в версии 3.5.2.789790#### `loop.default_exception_handler(context)`791792Обработчик исключений по умолчанию.793794Вызывается при возникновении исключения, если не установлен никакой обработчик. Может быть вызван пользовательским обработчиком, который хочет передать управление поведению по умолчанию.795796Параметр *context* имеет то же значение, что и в [`call_exception_handler()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_exception_handler).797798#### `loop.call_exception_handler(context)`799800Вызывает обработчик исключений текущего цикла событий.801802*context* – это объект `dict`, содержащий следующие ключи (в будущих версиях Python могут появиться новые ключи):803804- ‘message’: сообщение об ошибке;805- 'исключение' (необязательно): объект исключения;806- ‘future’ (необязательно): экземпляр [`asyncio.Future`](https://python-all.ru/3.11/library/asyncio-future.html#asyncio.Future);807- 'задача' (необязательно): экземпляр [`asyncio.Task`](https://python-all.ru/3.11/library/asyncio-task.html#asyncio.Task);808- ‘handle’ (необязательно): экземпляр [`asyncio.Handle`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Handle);809- 'протокол' (необязательно): экземпляр [Protocol](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-protocol);810- 'транспорт' (необязательно): экземпляр [Transport](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-transport);811- ‘socket’ (необязательно): экземпляр [`socket.socket`](https://python-all.ru/3.11/library/socket.html#socket.socket);812- **‘asyncgen’ (необязательно): асинхронный генератор, вызвавший**813814 исключение.815816> **Примечание**817>818> Этот метод не следует переопределять в подклассах циклов событий. Для настраиваемой обработки исключений используйте метод [`set_exception_handler()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.set_exception_handler).819820### [Включение режима отладки](https://python-all.ru/3.11/library/asyncio-eventloop.html#id16)821822#### `loop.get_debug()`823824Возвращает режим отладки ([`bool`](https://python-all.ru/3.11/library/functions.html#bool)) цикла событий.825826Значение по умолчанию – `True`, если переменная окружения [`PYTHONASYNCIODEBUG`](https://python-all.ru/3.11/using/cmdline.html#envvar-PYTHONASYNCIODEBUG) имеет непустое строковое значение, и `False` в противном случае.827828#### `loop.set_debug(enabled: bool)`829830Устанавливает режим отладки цикла событий.831832Изменено в версии 3.7: Новый [режим разработки Python](https://python-all.ru/3.11/library/devmode.html#devmode) теперь также можно использовать для включения режима отладки.833834#### `loop.slow_callback_duration`835836Этот атрибут можно использовать для задания минимальной продолжительности выполнения в секундах, которая считается «медленной». Если режим отладки включен, «медленные» колбэки регистрируются в журнале.837838Значение по умолчанию – 100 миллисекунд.839840> **См. также**841>842> [Режим отладки asyncio](https://python-all.ru/3.11/library/asyncio-dev.html#asyncio-debug-mode).843844### [Запуск подпроцессов](https://python-all.ru/3.11/library/asyncio-eventloop.html#id17)845846Методы, описанные в этом подразделе, являются низкоуровневыми. В обычном коде с async/await рекомендуется вместо них использовать высокоуровневые удобные функции [`asyncio.create_subprocess_shell()`](https://python-all.ru/3.11/library/asyncio-subprocess.html#asyncio.create_subprocess_shell) и [`asyncio.create_subprocess_exec()`](https://python-all.ru/3.11/library/asyncio-subprocess.html#asyncio.create_subprocess_exec).847848> **Примечание**849>850> В Windows цикл событий по умолчанию [`ProactorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.ProactorEventLoop) поддерживает подпроцессы, а [`SelectorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.SelectorEventLoop) – нет. Подробнее см. [Поддержка подпроцессов в Windows](https://python-all.ru/3.11/library/asyncio-platforms.html#asyncio-windows-subprocess).851852#### `coroutine loop.subprocess_exec(protocol_factory, *args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)`853854Создаёт подпроцесс из одного или нескольких строковых аргументов, заданных параметром *args*.855856Параметр *args* должен быть списком строк, представленным следующим образом:857858- [`str`](https://python-all.ru/3.11/library/stdtypes.html#str);859- или [`bytes`](https://python-all.ru/3.11/library/stdtypes.html#bytes), закодированная в [кодировку файловой системы](https://python-all.ru/3.11/library/os.html#filesystem-encoding).860861Первая строка указывает исполняемый файл программы, а остальные строки задают аргументы. Вместе строковые аргументы образуют `argv` программы.862863Это похоже на класс [`subprocess.Popen`](https://python-all.ru/3.11/library/subprocess.html#subprocess.Popen) из стандартной библиотеки, который вызывается с `shell=False` и списком строк, передаваемых в качестве первого аргумента; однако, если [`Popen`](https://python-all.ru/3.11/library/subprocess.html#subprocess.Popen) принимает один аргумент – список строк, *subprocess\_exec* принимает несколько строковых аргументов.864865Параметр *protocol\_factory* должен быть вызываемым объектом, возвращающим подкласс класса [`asyncio.SubprocessProtocol`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.SubprocessProtocol).866867Другие параметры:868869- *stdin* может принимать одно из следующих значений:870871 - Объект, похожий на файл, представляющий канал, подключаемый к стандартному потоку ввода подпроцесса с помощью [`connect_write_pipe()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.connect_write_pipe).872 - константа [`subprocess.PIPE`](https://python-all.ru/3.11/library/subprocess.html#subprocess.PIPE) (по умолчанию), которая создаст новый канал и подключит его,873 - значение `None`, которое заставляет подпроцесс наследовать файловый дескриптор от этого процесса874 - константа [`subprocess.DEVNULL`](https://python-all.ru/3.11/library/subprocess.html#subprocess.DEVNULL), указывающая, что будет использоваться специальный файл [`os.devnull`](https://python-all.ru/3.11/library/os.html#os.devnull)875- *stdout* может принимать одно из следующих значений:876877 - Объект, похожий на файл, представляющий канал, подключаемый к стандартному потоку вывода подпроцесса с помощью [`connect_write_pipe()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.connect_write_pipe).878 - константа [`subprocess.PIPE`](https://python-all.ru/3.11/library/subprocess.html#subprocess.PIPE) (по умолчанию), которая создаст новый канал и подключит его,879 - значение `None`, которое заставляет подпроцесс наследовать файловый дескриптор от этого процесса880 - константа [`subprocess.DEVNULL`](https://python-all.ru/3.11/library/subprocess.html#subprocess.DEVNULL), указывающая, что будет использоваться специальный файл [`os.devnull`](https://python-all.ru/3.11/library/os.html#os.devnull)881- *stderr* может принимать одно из следующих значений:882883 - Объект, похожий на файл, представляющий канал, подключаемый к стандартному потоку ошибок подпроцесса с помощью [`connect_write_pipe()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.connect_write_pipe).884 - константа [`subprocess.PIPE`](https://python-all.ru/3.11/library/subprocess.html#subprocess.PIPE) (по умолчанию), которая создаст новый канал и подключит его,885 - значение `None`, которое заставляет подпроцесс наследовать файловый дескриптор от этого процесса886 - константа [`subprocess.DEVNULL`](https://python-all.ru/3.11/library/subprocess.html#subprocess.DEVNULL), указывающая, что будет использоваться специальный файл [`os.devnull`](https://python-all.ru/3.11/library/os.html#os.devnull)887 - константа [`subprocess.STDOUT`](https://python-all.ru/3.11/library/subprocess.html#subprocess.STDOUT), которая подключает поток стандартной ошибки к потоку стандартного вывода процесса888- Все остальные именованные аргументы передаются в [`subprocess.Popen`](https://python-all.ru/3.11/library/subprocess.html#subprocess.Popen) без интерпретации, за исключением *bufsize*, *universal\_newlines*, *shell*, *text*, *encoding* и *errors*, которые не должны указываться вовсе.889890 API подпроцессов `asyncio` не поддерживает декодирование потоков как текст. Для преобразования байтов, возвращаемых из потока, в текст можно использовать [`bytes.decode()`](https://python-all.ru/3.11/library/stdtypes.html#bytes.decode).891892Описание остальных аргументов см. в конструкторе класса [`subprocess.Popen`](https://python-all.ru/3.11/library/subprocess.html#subprocess.Popen).893894Возвращает пару из `(transport, protocol)`, где *транспорт* соответствует базовому классу [`asyncio.SubprocessTransport`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.SubprocessTransport), а *протокол* – объект, созданный фабрикой *protocol\_factory*.895896#### `coroutine loop.subprocess_shell(protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)`897898Создаёт подпроцесс из *cmd*, который может быть строкой [`str`](https://python-all.ru/3.11/library/stdtypes.html#str) или [`bytes`](https://python-all.ru/3.11/library/stdtypes.html#bytes), закодированной в [кодировку файловой системы](https://python-all.ru/3.11/library/os.html#filesystem-encoding), используя синтаксис командной оболочки платформы («shell»).899900Это похоже на [`subprocess.Popen`](https://python-all.ru/3.11/library/subprocess.html#subprocess.Popen) класс из стандартной библиотеки, вызываемый с помощью `shell=True`.901902Параметр *protocol\_factory* должен быть вызываемым объектом, возвращающим подкласс класса [`SubprocessProtocol`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.SubprocessProtocol).903904Подробнее об остальных аргументах см. в [`subprocess_exec()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec).905906Возвращает пару из `(transport, protocol)`, где *транспорт* соответствует базовому классу [`SubprocessTransport`](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio.SubprocessTransport), а *протокол* – объект, созданный фабрикой *protocol\_factory*.907908> **Примечание**909>910> Ответственность за то, чтобы все пробельные и специальные символы были правильно экранированы, лежит на приложении – это позволяет избежать уязвимостей [инъекции команд оболочки](https://python-all.ru/3.11/library/asyncio-eventloop.html). Для корректного экранирования пробелов и спецсимволов в строках, используемых при построении команд оболочки, можно применить функцию [`shlex.quote()`](https://python-all.ru/3.11/library/shlex.html#shlex.quote).911912## Дескрипторы колбэков913914#### `class asyncio.Handle`915916Объект-обёртка колбэка, возвращаемый [`loop.call_soon()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_soon), [`loop.call_soon_threadsafe()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_soon_threadsafe).917918#### `cancel()`919920Отменяет колбэк. Если колбэк уже был отменён или выполнен, этот метод не делает ничего.921922#### `cancelled()`923924Возвращает `True`, если колбэк был отменён.925926Добавлено в версии 3.7.927928#### `class asyncio.TimerHandle`929930Объект-обёртка колбэка, возвращаемый [`loop.call_later()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_later) и [`loop.call_at()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_at).931932Этот класс является подклассом [`Handle`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Handle).933934#### `when()`935936Возвращает запланированное время выполнения колбэка в секундах [`float`](https://python-all.ru/3.11/library/functions.html#float).937938Время – абсолютная временная метка, использующая ту же систему отсчёта, что и [`loop.time()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.time).939940Добавлено в версии 3.7.941942## Объекты сервера943944Объекты сервера создаются функциями [`loop.create_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_server), [`loop.create_unix_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_unix_server), [`start_server()`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.start_server) и [`start_unix_server()`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.start_unix_server).945946Не следует создавать экземпляры класса [`Server`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Server) напрямую.947948#### `class asyncio.Server`949950Объекты *Server* являются асинхронными контекстными менеджерами. При использовании в операторе `async with` гарантируется, что объект Server будет закрыт и не будет принимать новые подключения после завершения оператора `async with`:951952```python953srv = await loop.create_server(...)954955async with srv:956 # некоторый код957958# На данный момент srv закрыт и больше не принимает новые соединения.959```960961Изменено в версии 3.7: Объект Server является асинхронным контекстным менеджером начиная с Python 3.7.962963Изменено в версии 3.11: Этот класс стал общедоступным как `asyncio.Server` в Python 3.9.11, 3.10.3 и 3.11.964965#### `close()`966967Прекращает обслуживание: закрывает слушающие сокеты и устанавливает атрибут [`sockets`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Server.sockets) в `None`.968969Сокеты, представляющие существующие входящие клиентские подключения, остаются открытыми.970971Сервер закрывается асинхронно, используйте [`wait_closed()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Server.wait_closed)\\nкорутину, чтобы дождаться закрытия сервера.972973#### `get_loop()`974975Возвращает цикл событий, связанный с объектом сервера.976977Добавлено в версии 3.7.978979#### `coroutine start_serving()`980981Начинает принимать соединения.982983Этот метод идемпотентен, поэтому его можно вызывать, когда сервер уже работает.984985Параметр *start\_serving*, передаваемый только по ключевому слову, в [`loop.create_server()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_server) и [`asyncio.start_server()`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.start_server) позволяет создать объект Server, который изначально не принимает соединения. В этом случае можно использовать `Server.start_serving()` или [`Server.serve_forever()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Server.serve_forever), чтобы заставить Server начать принимать соединения.986987Добавлено в версии 3.7.988989#### `coroutine serve_forever()`990991Начинает принимать соединения до отмены корутины. Отмена задачи `serve_forever` приводит к закрытию сервера.992993Этот метод можно вызывать, если сервер уже принимает соединения. Для одного объекта *Server* может существовать только одна задача `serve_forever`.994995Пример:996997```python998async def client_connected(reader, writer):999 # Общение с клиентом через1000 # потоки чтения/записи. Например:1001 await reader.readline()10021003async def main(host, port):1004 srv = await asyncio.start_server(1005 client_connected, host, port)1006 await srv.serve_forever()10071008asyncio.run(main('127.0.0.1', 0))1009```10101011Добавлено в версии 3.7.10121013#### `is_serving()`10141015Возвращает `True`, если сервер принимает новые соединения.10161017Добавлено в версии 3.7.10181019#### `coroutine wait_closed()`10201021Ожидайте завершения метода [`close()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.Server.close).10221023#### `sockets`10241025Список объектов, подобных сокетам, `asyncio.trsock.TransportSocket`, на которых сервер прослушивает соединения.10261027Изменено в версии 3.7: До Python 3.7 `Server.sockets` возвращал внутренний список серверных сокетов напрямую. В версии 3.7 возвращается копия этого списка.10281029## Реализации цикла событий10301031asyncio поставляется с двумя различными реализациями цикла событий: [`SelectorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.SelectorEventLoop) и [`ProactorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.ProactorEventLoop).10321033По умолчанию asyncio настроено на использование [`SelectorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.SelectorEventLoop) в Unix и [`ProactorEventLoop`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.ProactorEventLoop) в Windows.10341035#### `class asyncio.SelectorEventLoop`10361037Цикл событий на основе модуля [`selectors`](https://python-all.ru/3.11/library/selectors.html#module-selectors).10381039Использует наиболее эффективный *селектор*, доступный для данной платформы. Также можно вручную настроить конкретную реализацию селектора:10401041```python1042import asyncio1043import selectors10441045class MyPolicy(asyncio.DefaultEventLoopPolicy):1046 def new_event_loop(self):1047 selector = selectors.SelectSelector()1048 return asyncio.SelectorEventLoop(selector)10491050asyncio.set_event_loop_policy(MyPolicy())1051```10521053[Доступность](https://python-all.ru/3.11/library/intro.html#availability): Unix, Windows.10541055#### `class asyncio.ProactorEventLoop`10561057Цикл событий для Windows, использующий «порты завершения ввода-вывода» (IOCP).10581059[Доступность](https://python-all.ru/3.11/library/intro.html#availability): Windows.10601061> **См. также**1062>1063> [документация MSDN по портам завершения ввода-вывода](https://python-all.ru/3.11/library/asyncio-eventloop.html).10641065#### `class asyncio.AbstractEventLoop`10661067Абстрактный базовый класс для циклов событий, совместимых с asyncio.10681069Раздел [Методы цикла событий](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio-event-loop-methods) перечисляет все методы, которые должна определять альтернативная реализация `AbstractEventLoop` .10701071## Примеры10721073Обратите внимание, что все примеры в этом разделе **намеренно** показывают, как использовать низкоуровневые API цикла событий, такие как [`loop.run_forever()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.run_forever) и [`loop.call_soon()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_soon). Современные приложения asyncio редко требуют такого стиля написания; рекомендуется использовать высокоуровневые функции, такие как [`asyncio.run()`](https://python-all.ru/3.11/library/asyncio-runner.html#asyncio.run).10741075### Hello World с call\_soon()10761077Пример использования метода [`loop.call_soon()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_soon) для планирования колбэка. Колбэк выводит `"Hello World"`, а затем останавливает цикл событий:10781079```python1080import asyncio10811082def hello_world(loop):1083 """Колбэк для вывода 'Hello World' и остановки цикла событий"""1084 print('Hello World')1085 loop.stop()10861087loop = asyncio.new_event_loop()10881089# Запланировать вызов hello_world()1090loop.call_soon(hello_world, loop)10911092# Блокирующий вызов прерван loop.stop()1093try:1094 loop.run_forever()1095finally:1096 loop.close()1097```10981099> **См. также**1100>1101> Аналогичный [пример Hello World](https://python-all.ru/3.11/library/asyncio-task.html#coroutine), созданный с помощью корутины и функции [`run()`](https://python-all.ru/3.11/library/asyncio-runner.html#asyncio.run).11021103### Отображение текущей даты с помощью call\_later()11041105Пример колбэка, выводящего текущую дату каждую секунду. Колбэк использует метод [`loop.call_later()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.call_later) для повторного планирования самого себя через 5 секунд, а затем останавливает цикл событий:11061107```python1108import asyncio1109import datetime11101111def display_date(end_time, loop):1112 print(datetime.datetime.now())1113 if (loop.time() + 1.0) < end_time:1114 loop.call_later(1, display_date, end_time, loop)1115 else:1116 loop.stop()11171118loop = asyncio.new_event_loop()11191120# Запланировать первый вызов display_date()1121end_time = loop.time() + 5.01122loop.call_soon(display_date, end_time, loop)11231124# Блокирующий вызов прерван loop.stop()1125try:1126 loop.run_forever()1127finally:1128 loop.close()1129```11301131> **См. также**1132>1133> Аналогичный [пример с текущей датой](https://python-all.ru/3.11/library/asyncio-task.html#asyncio-example-sleep), созданный с помощью корутины и функции [`run()`](https://python-all.ru/3.11/library/asyncio-runner.html#asyncio.run).11341135### Наблюдение за файловым дескриптором на события чтения11361137Ожидание, пока файловый дескриптор не получит некоторые данные, с помощью метода [`loop.add_reader()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.add_reader), после чего цикл событий закрывается:11381139```python1140import asyncio1141from socket import socketpair11421143# Создать пару связанных файловых дескрипторов1144rsock, wsock = socketpair()11451146loop = asyncio.new_event_loop()11471148def reader():1149 data = rsock.recv(100)1150 print("Received:", data.decode())11511152 # Готово: отменить регистрацию файлового дескриптора1153 loop.remove_reader(rsock)11541155 # Остановить цикл событий1156 loop.stop()11571158# Зарегистрировать файловый дескриптор для события чтения1159loop.add_reader(rsock, reader)11601161# Симулировать приём данных из сети1162loop.call_soon(wsock.send, 'abc'.encode())11631164try:1165 # Запустить цикл событий1166 loop.run_forever()1167finally:1168 # Готово. Закрыть сокеты и цикл событий.1169 rsock.close()1170 wsock.close()1171 loop.close()1172```11731174> **См. также**1175>1176> - Аналогичный [пример](https://python-all.ru/3.11/library/asyncio-protocol.html#asyncio-example-create-connection) с использованием транспортов, протоколов и метода [`loop.create_connection()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.create_connection).1177> - Ещё один аналогичный [пример](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio-example-create-connection-streams) с использованием высокоуровневой функции [`asyncio.open_connection()`](https://python-all.ru/3.11/library/asyncio-stream.html#asyncio.open_connection) и потоков данных.11781179### Установка обработчиков сигналов SIGINT и SIGTERM11801181(Этот `signals` пример работает только на Unix.)11821183Регистрация обработчиков для сигналов [`SIGINT`](https://python-all.ru/3.11/library/signal.html#signal.SIGINT) и [`SIGTERM`](https://python-all.ru/3.11/library/signal.html#signal.SIGTERM) с помощью метода [`loop.add_signal_handler()`](https://python-all.ru/3.11/library/asyncio-eventloop.html#asyncio.loop.add_signal_handler):11841185```python1186import asyncio1187import functools1188import os1189import signal11901191def ask_exit(signame, loop):1192 print("got signal %s: exit" % signame)1193 loop.stop()11941195async def main():1196 loop = asyncio.get_running_loop()11971198 for signame in {'SIGINT', 'SIGTERM'}:1199 loop.add_signal_handler(1200 getattr(signal, signame),1201 functools.partial(ask_exit, signame, loop))12021203 await asyncio.sleep(3600)12041205print("Event loop running for 1 hour, press Ctrl+C to interrupt.")1206print(f"pid {os.getpid()}: send SIGINT or SIGTERM to exit.")12071208asyncio.run(main())1209```1210