Цикл обработки событий
Исходный код: Lib/asyncio/events.py, Lib/asyncio/base_events.py
Предварительные замечания
Цикл обработки событий — это ядро любого приложения asyncio. Циклы обработки событий выполняют асинхронные задачи и обратные вызовы, выполняют операции ввода-вывода сети и запускают подпроцессы.
Разработчики приложений, как правило, должны использовать высокоуровневые функции asyncio, такие как asyncio.run(), и им редко требуется обращаться к объекту цикла или вызывать его методы. Этот раздел предназначен в основном для авторов кода нижнего уровня, библиотек и фреймворков, которым нужен более тонкий контроль над поведением цикла обработки событий.
Получение цикла обработки событий
Следующие функции низкого уровня могут использоваться для получения, установки или создания цикла обработки событий:
-
asyncio.get_running_loop() -
Возвращает работающий цикл обработки событий в текущей потоке ОС.
Вызовет исключение
RuntimeError, если работающий цикл обработки событий отсутствует.Эта функция может вызываться только из сопрограммы или обратного вызова.
Добавлена в версии 3.7.
-
asyncio.get_event_loop() -
Получает текущий цикл обработки событий.
При вызове из сопрограммы или обратного вызова (например, запланированного с помощью
call_soonили аналогичного API) эта функция всегда возвращает работающий цикл обработки событий.Если нет установленного работающего цикла обработки событий, функция вернёт результат вызова
get_event_loop_policy().get_event_loop().Поскольку эта функция имеет довольно сложное поведение (особенно при использовании пользовательских политик цикла обработки событий), использование функции
get_running_loop()предпочтительнее функцииget_event_loop()в сопрограммах и обратных вызовах.Как отмечалось выше, рассмотрите использование высокоуровневой функции
asyncio.run()вместо использования этих функций низкого уровня для ручного создания и закрытия цикла обработки событий.Устарело начиная с версии 3.12: Выдаётся предупреждение об устаревании, если текущий цикл обработки событий отсутствует. В будущих версиях Python это станет ошибкой.
-
asyncio.set_event_loop(loop) -
Устанавливает loop в качестве текущего цикла обработки событий для текущей потока ОС.
-
asyncio.new_event_loop() -
Создаёт и возвращает новый объект цикла обработки событий.
Обратите внимание, что поведение функций get_event_loop(), set_event_loop() и new_event_loop() может быть изменено с помощью установки пользовательской политики цикла обработки событий.
Содержание
Данная страница документации содержит следующие разделы:
- Раздел Методы цикла обработки событий содержит справочную документацию по API цикла обработки событий;
- Раздел Обработчики обратных вызовов документирует экземпляры
HandleиTimerHandle, которые возвращаются при планировании методов, таких какloop.call_soon()иloop.call_later(); - Раздел Объекты сервера документирует типы, возвращаемые методами цикла обработки событий, такими как
loop.create_server(); - Раздел Реализации цикла обработки событий документирует классы
SelectorEventLoopиProactorEventLoop; - Раздел Примеры демонстрирует работу с некоторыми API цикла обработки событий.
Методы цикла событий
Циклы событий имеют низкоуровневые API для следующего:
- Запуск и остановка цикла
- Планирование обратных вызовов
- Планирование отложенных обратных вызовов
- Создание объектов Future и Task
- Открытие сетевых соединений
- Создание сетевых серверов
- Передача файлов
- Обновление TLS
- Наблюдение за дескрипторами файлов
- Работа с объектами сокетов напрямую
- DNS
- Работа с каналами
- Сигналы Unix
- Выполнение кода в пулах потоков или процессов
- API обработки ошибок
- Включение режима отладки
- Запуск дочерних процессов
Запуск и остановка цикла
-
loop.run_until_complete(future) -
Запуск, пока future (экземпляр
Future) не завершится.Если аргументом является объект корутины, он неявно запланирован для выполнения как
asyncio.Task.Возвращает результат Future или поднимает его исключение.
-
loop.run_forever() -
Запуск цикла событий до вызова
stop().Если
stop()вызван до вызоваrun_forever(), цикл обследует селектор ввода/вывода один раз с таймаутом 0, выполнит все обратные вызовы, запланированные в ответ на события ввода/вывода (и те, которые уже были запланированы), и затем завершится.Если
stop()вызван во время работыrun_forever(), цикл выполнит текущую партию обратных вызовов, а затем завершится. Обратите внимание, что новые обратные вызовы, запланированные обратными вызовами, не будут выполнены в этом случае; вместо этого они будут выполнены в следующий раз, когда будет вызванrun_forever()илиrun_until_complete().
-
loop.stop() -
Остановить цикл событий.
-
loop.is_running() -
Возвращает
True, если цикл событий в данный момент работает.
-
loop.is_closed() -
Возвращает
True, если цикл событий был закрыт.
-
loop.close() -
Закрыть цикл событий.
Цикл не должен выполняться при вызове этой функции. Любые ожидающие обратные вызовы будут отброшены.
Этот метод очищает все очереди и завершает исполняемый модуль, но не ожидает завершения исполняемого модуля.
Этот метод идемпотентен и необратим. Никакие другие методы не должны вызываться после закрытия цикла событий.
-
coroutine loop.shutdown_asyncgens() -
Планирует закрытие всех открытых в данный момент объектов асинхронных генераторов с вызовом
aclose(). После вызова этого метода цикл событий выдаст предупреждение, если новый асинхронный генератор будет итерироваться. Это необходимо для надёжной финализации всех запланированных асинхронных генераторов.Обратите внимание, что вызывать эту функцию нет необходимости при использовании
asyncio.run().Пример:
try: loop.run_forever() finally: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close()Добавлена в версии 3.6.
-
coroutine loop.shutdown_default_executor(timeout=None) -
Планирует закрытие исполняемого модуля по умолчанию и ожидает его завершения, объединяя все потоки в
ThreadPoolExecutor. После вызова этого метода использование исполняемого модуля по умолчанию сloop.run_in_executor()вызоветRuntimeError.Параметр timeout задаёт время (в секундах
float), которое будет дано исполняемому модулю на завершение объединения. По умолчанию,None, исполняемому модулю предоставляется неограниченное время.Если таймаут достигнут, генерируется
RuntimeWarning, и исполняемый модуль по умолчанию завершается без ожидания завершения объединения потоков.Примечание
Не вызывайте этот метод при использовании
asyncio.run(), так как последний автоматически обрабатывает закрытие исполняемого модуля по умолчанию.Добавлена в версии 3.9.
Изменено в версии 3.12: Добавлен параметр timeout.
Планирование обратных вызовов
-
loop.call_soon(callback, *args, context=None) -
Запланировать обратный вызов callback с аргументами args на следующей итерации цикла событий.
Возвращает экземпляр
asyncio.Handle, который позже может использоваться для отмены обратного вызова.Обратные вызовы вызываются в порядке их регистрации. Каждый обратный вызов будет вызван ровно один раз.
Необязательный ключевой параметр context указывает пользовательский
contextvars.Contextдля выполнения callback. Обратные вызовы используют текущий контекст, если context не указан.В отличие от
call_soon_threadsafe(), этот метод не потокобезопасен.
-
loop.call_soon_threadsafe(callback, *args, context=None) -
Потокобезопасная версия
call_soon(). При планировании обратных вызовов из другого потока необходимо использовать эту функцию, так какcall_soon()не потокобезопасна.Вызывает
RuntimeError, если вызывается в цикле, который закрыт. Это может произойти во вторичном потоке, когда основное приложение завершается.См. раздел конкурентности и многопоточности документации.
Изменено в версии 3.7: Добавлен ключевой параметр context. См. PEP 567 для получения дополнительной информации.
Примечание
Большинство функций планирования asyncio не позволяют передавать ключевые аргументы. Для этого используйте functools.partial():
# will schedule "print("Hello", flush=True)"
loop.call_soon(
functools.partial(print, "Hello", flush=True))
Использование частичных объектов обычно удобнее, чем использование лямбда-функций, так как asyncio может лучше отображать частичные объекты в отладочных и сообщений об ошибках.
Планирование отложенных обратных вызовов
Цикл событий предоставляет механизмы для планирования обратных вызовов функций, которые должны быть вызваны в какой-то момент в будущем. Цикл событий использует монотонные часы для отслеживания времени.
-
loop.call_later(delay, callback, *args, context=None) -
Запланировать вызов callback после заданного delay количества секунд (может быть целым или дробным числом).
Возвращается экземпляр
asyncio.TimerHandle, который может быть использован для отмены обратного вызова.callback будет вызван ровно один раз. Если два обратных вызова запланированы ровно на одно и то же время, порядок их вызова не определён.
Дополнительные позиционные аргументы args будут переданы обратному вызову при его вызове. Если вы хотите, чтобы обратный вызов вызывался с аргументами ключевого слова, используйте
functools.partial().Необязательный аргумент context позволяет указать пользовательский
contextvars.Contextдля выполнения callback. Текущий контекст используется, если context не указан.Изменено в версии 3.7: Добавлен ключевой параметр context. Подробнее см. PEP 567.
Изменено в версии 3.8: В Python 3.7 и ранее с реализацией цикла событий по умолчанию delay не мог превышать одного дня. Эта проблема исправлена в Python 3.8.
-
loop.call_at(when, callback, *args, context=None) -
Запланировать вызов callback на указанную абсолютную временную метку when (целое или дробное число), используя ту же временную базу, что и
loop.time().Поведение этого метода такое же, как у
call_later().Возвращается экземпляр
asyncio.TimerHandle, который можно использовать для отмены обратного вызова.Изменено в версии 3.7: Добавлен ключевой параметр context. Подробнее см. PEP 567.
Изменено в версии 3.8: В Python 3.7 и ранее разница между when и текущим временем не могла превышать одного дня. Эта проблема исправлена в Python 3.8.
-
loop.time() -
Возвращает текущее время как значение
floatсогласно внутренним монотонным часам цикла событий.
Примечание
Изменено в версии 3.8: В Python 3.7 и ранее таймауты (относительный delay или абсолютный when) не должны превышать один день. Эта проблема исправлена в Python 3.8.
См. также
Функцию asyncio.sleep().
Создание объектов Future и задач
-
loop.create_future() -
Создаёт объект
asyncio.Future, привязанный к циклу событий.Это предпочтительный способ создания объектов Future в asyncio. Это позволяет сторонним циклам событий предоставлять альтернативные реализации объекта Future (с лучшей производительностью или инструментированием).
Добавлен в версии 3.5.2.
-
loop.create_task(coro, *, name=None, context=None) -
Планирует выполнение корутины coro. Возвращает объект
Task.Сторонние циклы событий могут использовать собственный подкласс
Taskдля межплатформенной совместимости. В этом случае тип результата является подклассомTask.Если указан аргумент name и он не
None, он устанавливается как имя задачи, используяTask.set_name().Необязательный ключевой аргумент context позволяет указать пользовательский
contextvars.Contextдля выполнения coro. Копия текущего контекста создается, если context не указан.Изменено в версии 3.8: Добавлен параметр name.
Изменено в версии 3.11: Добавлен параметр context.
-
loop.set_task_factory(factory) -
Устанавливает фабрику задач, которая будет использоваться
loop.create_task().Если factory
None, будет установлена по умолчанию фабрика задач. В противном случае factory должен быть вызываемым с сигнатурой, соответствующей(loop, coro, context=None), где loop — ссылка на активный цикл событий, а coro — объект корутины. Вызываемый объект должен возвращать объект, совместимый сasyncio.Future.
-
loop.get_task_factory() -
Возвращает фабрику задач или
Noneесли используется по умолчанию.
Открытие сетевых подключений
-
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, all_errors=False) -
Установить поток подключение к заданному адресу, указанному host и port.
Семейство сокетов может быть либо
AF_INET, либоAF_INET6в зависимости от host (или аргумента family, если он указан).Тип сокета будет
SOCK_STREAM.protocol_factory должно быть вызываемым объектом, возвращающим реализацию протокола asyncio.
Этот метод попытается установить соединение в фоновом режиме. При успехе он вернет пару
(transport, protocol).Хронологический обзор базовой операции:
- Подключение устанавливается, и для него создается транспорт.
- protocol_factory вызывается без аргументов и ожидается, что вернёт экземпляр протокола.
- Экземпляр протокола связывается с транспортом, вызвав его метод
connection_made(). - В случае успеха возвращается кортеж
(transport, protocol).
Созданный транспорт — это двунаправленный поток, реализация которого зависит от конкретной системы.
Другие аргументы:
-
ssl: если указан и не равен false, создаётся SSL/TLS транспорт (по умолчанию создаётся обычный TCP транспорт). Если ssl — объект
ssl.SSLContext, этот контекст используется для создания транспорта; если ssl равенTrue, используется контекст по умолчанию, возвращённый изssl.create_default_context().См. также
-
server_hostname устанавливает или переопределяет имя хоста, по которому будет проверяться сертификат целевого сервера. Должен передаваться только если ssl не
None. По умолчанию используется значение аргумента host. Если host пустой, по умолчанию значение не устанавливается, и вы должны передать значение для server_hostname. Если server_hostname — пустая строка, проверка имени хоста отключена (что является серьёзной проблемой безопасности, позволяющей потенциальным атакам типа «человек посередине»). -
family, proto, flags — необязательные семейство адреса, протокол и флаги, передаваемые в getaddrinfo() для разрешения host. Если указаны, они должны быть целыми числами из соответствующих констант модуля
socket. -
happy_eyeballs_delay, если задан, включает Happy Eyeballs для этого подключения. Это число с плавающей точкой, представляющее количество секунд ожидания завершения попытки подключения, прежде чем начать следующую попытку параллельно. Это «Задержка попытки подключения», как определено в RFC 8305. Рекомендуемое разумное значение по умолчанию, рекомендованное RFC, равно
0.25(250 миллисекунд). -
interleave управляет упорядочиванием адресов при разрешении имени хоста на несколько IP-адресов. Если
0или не указано, упорядочивание не выполняется, и адреса обрабатываются в порядке, возвращённомgetaddrinfo(). Если указано положительное целое число, адреса интерливируются по семействам адресов, и заданное целое число интерпретируется как «Количество семейств адресов в первую очередь», как определено в RFC 8305. Значение по умолчанию равно0если happy_eyeballs_delay не указано, и1если оно указано. -
sock, если задан, должен быть существующим, уже подключённым объектом
socket.socket, который будет использоваться транспортом. Если sock задан, не должны указываться host, port, family, proto, flags, happy_eyeballs_delay, interleave, local_addr.Примечание
Аргумент sock передает право собственности на сокет созданному транспорту. Для закрытия сокета вызовите метод транспорта
close(). -
local_addr, если задан, — это кортеж
(local_host, local_port)используемый для привязки сокета локально. local_host и local_port ищутся с помощьюgetaddrinfo(), аналогично host и port. -
ssl_handshake_timeout (для TLS-соединения) — время в секундах ожидания завершения рукопожатия TLS перед прерыванием соединения.
60.0секунд еслиNone(по умолчанию). -
ssl_shutdown_timeout — время в секундах ожидания завершения закрытия SSL перед прерыванием соединения.
30.0секунд еслиNone(по умолчанию). -
all_errors определяет, какие исключения генерируются при невозможности создания подключения. По умолчанию генерируется только одно исключение
Exception: первое исключение, если их только одно, или все ошибки имеют одинаковое сообщение, или одно исключениеOSErrorс объединёнными сообщениями об ошибках. Когдаall_errorsравноTrue, будет генерировано исключениеExceptionGroup, содержащее все исключения (даже если их только одно).
Изменено в версии 3.5: Добавлена поддержка SSL/TLS в
ProactorEventLoop.Изменено в версии 3.6: Опция сокета socket.TCP_NODELAY установлена по умолчанию для всех TCP-соединений.
Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout.
Изменено в версии 3.8: Добавлены параметры happy_eyeballs_delay и interleave.
Алгоритм Happy Eyeballs: Успех с хостами с двойной адресацией. Когда рабочий путь и протокол сервера IPv4, но путь и протокол сервера IPv6 не работают, приложение клиента с двойной адресацией испытывает значительную задержку подключения по сравнению с клиентом, работающим только с IPv4. Это нежелательно, так как заставляет клиента с двойной адресацией иметь худший пользовательский опыт. Данный документ определяет требования к алгоритмам, которые уменьшают эту видимую пользователю задержку, и предоставляет алгоритм.
Дополнительная информация: https://datatracker.ietf.org/doc/html/rfc6555
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
Изменено в версии 3.12: Добавлен all_errors.
См. также
Функция
open_connection()— это альтернативный API высокого уровня. Она возвращает пару (StreamReader,StreamWriter), которую можно использовать непосредственно в коде async/await.
-
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) -
Создать соединение датаграмм.
Семейство сокета может быть
AF_INET,AF_INET6илиAF_UNIX, в зависимости от host (или аргумента family, если он указан).Тип сокета будет
SOCK_DGRAM.protocol_factory должно быть вызываемой функцией, возвращающей реализацию протокола.
В случае успеха возвращается кортеж
(transport, protocol).Другие аргументы:
-
local_addr, если указан, — кортеж
(local_host, local_port), используемый для привязки сокета локально. local_host и local_port ищутся с помощьюgetaddrinfo(). -
remote_addr, если указан, — кортеж
(remote_host, remote_port), используемый для подключения сокета к удалённому адресу. remote_host и remote_port ищутся с помощьюgetaddrinfo(). -
family, proto, flags — необязательные семейство адресов, протокол и флаги, которые передаются в
getaddrinfo()для разрешения host. Если указаны, они должны быть целыми числами из соответствующих констант модуляsocket. - reuse_port сообщает ядру, что этому конечной точке разрешено быть привязанной к тому же порту, что и другим существующим конечным точкам, при условии, что все они устанавливают этот флаг при создании. Этот параметр не поддерживается в Windows и некоторых Unixes. Если константа socket.SO_REUSEPORT не определена, то эта возможность не поддерживается.
- allow_broadcast сообщает ядру, что этой конечной точке разрешено отправлять сообщения на адрес широковещательной передачи.
-
sock можно указать для использования существующего, уже подключённого объекта
socket.socketтранспортным средством. Если указан, local_addr и remote_addr должны быть опушены (должны бытьNone).Примечание
Аргумент sock передаёт владение сокетом созданному транспортному средству. Для закрытия сокета вызовите метод
close()транспортного средства.
См. примеры протокола UDP-эхо-клиента и протокола UDP-эхо-сервера.
Изменено в версии 3.4.4: Добавлены параметры family, proto, flags, reuse_address, reuse_port, allow_broadcast и sock.
Изменено в версии 3.8: Добавлена поддержка Windows.
Изменено в версии 3.8.1: Параметр reuse_address больше не поддерживается, так как использование socket.SO_REUSEADDR представляет значительную угрозу безопасности для UDP. Явное указание
reuse_address=Trueвызовет исключение.Когда несколько процессов с разными идентификаторами пользователей назначают сокеты идентичному UDP-адресу сокета с
SO_REUSEADDR, входящие пакеты могут быть случайным образом распределены между сокетами.Для поддерживаемых платформ можно использовать reuse_port в качестве замены аналогичной функциональности. При использовании reuse_port вместо него используется socket.SO_REUSEPORT, что специально предотвращает назначение сокетов тем же адресом сокета процессам с разными идентификаторами пользователей.
Изменено в версии 3.11: Параметр reuse_address, отключенный с Python 3.8.1, 3.7.6 и 3.6.10, был полностью удалён.
-
local_addr, если указан, — кортеж
-
coroutine loop.create_unix_connection(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None) -
Создать соединение Unix.
Семейство сокета будет
AF_UNIX; тип сокета будетSOCK_STREAM.В случае успеха возвращается кортеж
(transport, protocol).path — имя сокета Unix-домена и требуется, если не указан параметр sock. Поддерживаются абстрактные сокеты Unix, пути
str,bytesиPath.См. документацию метода
loop.create_connection()для получения информации об аргументах этого метода.Доступность: Unix.
Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout. Параметр path теперь может быть объектом, подобным пути.
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
Создание сетевых серверов
-
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) -
Создаёт TCP-сервер (тип сокета
SOCK_STREAM), прослушивающий порт port на адресе host.Возвращает объект
Server.Аргументы:
- protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола.
-
Параметр host может принимать несколько типов, определяющих место прослушивания сервера:
- Если host является строкой, TCP-сервер привязывается к одному сетевому интерфейсу, указанному в host.
- Если host является последовательностью строк, TCP-сервер привязывается ко всем сетевым интерфейсам, указанным в последовательности.
- Если host является пустой строкой или
None, предполагаются все интерфейсы, и будет возвращён список нескольких сокетов (вероятно, один для IPv4 и другой для IPv6).
- Параметр port может быть установлен для указания порта, на котором сервер должен прослушивать. Если
0илиNone(по умолчанию), будет выбран случайный свободный порт (обратите внимание, что если host разрешается на несколько сетевых интерфейсов, для каждого интерфейса будет выбран другой случайный порт). -
family может быть установлен либо в
socket.AF_INET, либо вAF_INET6, чтобы принудительно использовать IPv4 или IPv6 сокет. Если не задан, family определяется по имени хоста (по умолчаниюAF_UNSPEC). -
flags — битовая маска для
getaddrinfo(). -
sock может быть необязательно указан для использования существующего объекта сокета. Если указан, host и port не должны быть указаны.
Примечание
Аргумент sock передаёт владение сокетом созданному серверу. Для закрытия сокета вызовите метод
close()сервера. -
backlog — максимальное количество поставленных в очередь соединений, передаваемое в
listen()(по умолчанию 100). -
ssl может быть установлен в экземпляр
SSLContextдля включения TLS для принятых соединений. -
reuse_address сообщает ядру использовать локальный сокет в состоянии
TIME_WAIT, без ожидания истечения его естественного таймаута. Если не указан, автоматически будет установлен вTrueна Unix. - reuse_port сообщает ядру разрешить этому конечной точке быть привязанной к тому же порту, что и другие существующие конечные точки, при условии, что все они устанавливают этот флаг при создании. Этот параметр не поддерживается в Windows.
-
ssl_handshake_timeout (для TLS-сервера) — время в секундах ожидания завершения TLS-рукопожатия перед прерыванием соединения.
60.0секунд, еслиNone(по умолчанию). -
ssl_shutdown_timeout — время в секундах ожидания завершения SSL-закрытия перед прерыванием соединения.
30.0секунд, еслиNone(по умолчанию). -
start_serving, установленный в
True(по умолчанию), заставляет созданный сервер немедленно начать принимать подключения. При установке вFalse, пользователь должен ожидатьServer.start_serving()илиServer.serve_forever()для начала приёма подключений.
Изменено в версии 3.5: Добавлена поддержка SSL/TLS в
ProactorEventLoop.Изменено в версии 3.5.1: Параметр host может быть последовательностью строк.
Изменено в версии 3.6: Добавлены параметры ssl_handshake_timeout и start_serving. Параметр socket.TCP_NODELAY по умолчанию устанавливается для всех TCP-соединений.
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
См. также
Функция
start_server()— это альтернативный API более высокого уровня, который возвращает паруStreamReaderиStreamWriter, которые можно использовать в коде async/await.
-
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) -
Аналогично
loop.create_server(), но работает с семейством сокетовAF_UNIX.path — имя Unix-доменного сокета, и является обязательным, если не указан аргумент sock. Поддерживаются пути абстрактных Unix-сокетов,
str,bytesиPath.См. документацию метода
loop.create_server()для получения информации об аргументах этого метода.Доступность: Unix.
Изменено в версии 3.7: Добавлены параметры ssl_handshake_timeout и start_serving. Параметр path теперь может быть объектом
Path.Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
-
coroutine loop.connect_accepted_socket(protocol_factory, sock, *, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None) -
Оборачивает уже принятое соединение в пару транспорт/протокол.
Этот метод может использоваться серверами, которые принимают подключения вне asyncio, но используют asyncio для их обработки.
Параметры:
- protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола.
-
sock — существующий объект сокета, возвращённый из
socket.accept.Примечание
Аргумент sock передаёт владение сокетом созданному транспорту. Для закрытия сокета вызовите метод
close()транспорта. -
ssl может быть установлен в
SSLContextдля включения SSL для принятых соединений. -
ssl_handshake_timeout (для SSL-соединения) — время в секундах ожидания завершения SSL-рукопожатия перед прерыванием соединения.
60.0секунд, еслиNone(по умолчанию). -
ssl_shutdown_timeout — время в секундах ожидания завершения SSL-закрытия перед прерыванием соединения.
30.0секунд, еслиNone(по умолчанию).
Возвращает пару
(transport, protocol).Добавлен в версии 3.5.3.
Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout.
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
Передача файлов
-
coroutine loop.sendfile(transport, file, offset=0, count=None, *, fallback=True) -
Отправить файл по транспорту. Вернуть общее количество отправленных байтов.
Метод использует высокопроизводительный метод
os.sendfile(), если он доступен.Файл должен быть объектом обычного файла, открытого в двоичном режиме.
Смещение указывает, с какой позиции начать чтение файла. Если указано, количество — это общее количество байтов для передачи, а не передача файла до достижения конца файла. Позиция файла всегда обновляется, даже когда этот метод вызывает ошибку, и можно использовать
file.tell()для получения фактического количества отправленных байтов.Fallback, установленный в
True, заставляет asyncio вручную читать и отправлять файл, когда платформа не поддерживает системный вызов sendfile (например, Windows или сокет SSL на Unix).Вызовите
SendfileNotAvailableError, если система не поддерживает системный вызов sendfile, а fallback равенFalse.Добавлен в версии 3.7.
Обновление TLS
-
coroutine loop.start_tls(transport, protocol, sslcontext, *, server_side=False, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None) -
Обновить существующее подключение на основе транспорта до TLS.
Создать экземпляр кодера/декодера TLS и вставить его между транспортом и протоколом. Кодер/декодер реализует протокол, ориентированный на транспорт, и транспорт, ориентированный на протокол.
Вернуть созданный экземпляр с двумя интерфейсами. После await протокол должен перестать использовать исходный транспорт и взаимодействовать только с возвращенным объектом, потому что кодер кэширует данные со стороны протокола и периодически обменивается дополнительными пакетами сеанса TLS с транспортом.
В некоторых ситуациях (например, когда передаваемый транспорт уже закрывается) это может вернуть
None.Параметры:
-
экземпляры транспорта и протокола, которые возвращают методы, такие как
create_server()иcreate_connection(). -
sslcontext: настроенный экземпляр
SSLContext. -
server_side передать
Trueпри обновлении подключения на стороне сервера (например, такого, который был создан методомcreate_server()). - server_hostname: устанавливает или переопределяет имя хоста, с которым будет сравниваться сертификат целевого сервера.
-
ssl_handshake_timeout — время в секундах ожидания завершения рукопожатия TLS перед прерыванием соединения.
60.0секунд, еслиNone(по умолчанию). -
ssl_shutdown_timeout — время в секундах ожидания завершения закрытия SSL перед прерыванием соединения.
30.0секунд, еслиNone(по умолчанию).
Добавлен в версии 3.7.
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
-
экземпляры транспорта и протокола, которые возвращают методы, такие как
Отслеживание дескрипторов файлов
-
loop.add_reader(fd, callback, *args) -
Начать мониторинг дескриптора файла fd на доступность для чтения и вызвать callback со специфицированными аргументами, как только fd станет доступным для чтения.
-
loop.remove_reader(fd) -
Остановить мониторинг дескриптора файла fd на доступность для чтения. Возвращает
Trueесли fd ранее отслеживался на чтение.
-
loop.add_writer(fd, callback, *args) -
Начать мониторинг дескриптора файла fd на доступность для записи и вызвать callback со специфицированными аргументами, как только fd станет доступным для записи.
Используйте
functools.partial()для передачи аргументов по ключевым словам в callback.
-
loop.remove_writer(fd) -
Остановить мониторинг дескриптора файла fd на доступность для записи. Возвращает
Trueесли fd ранее отслеживался на запись.
См. также раздел Поддержка платформ для некоторых ограничений этих методов.
Работа с объектами сокетов напрямую
В общем случае, реализации протоколов, использующие транспортные API, такие как loop.create_connection() и loop.create_server(), быстрее, чем реализации, работающие напрямую с сокетами. Однако, есть некоторые случаи использования, когда производительность не критична, и работа с объектами socket напрямую более удобна.
-
coroutine loop.sock_recv(sock, nbytes) -
Принимает до nbytes байтов из sock. Асинхронная версия
socket.recv().Возвращает полученные данные в виде объекта bytes.
sock должен быть сокетом в режиме без ожидания.
Изменено в версии 3.7: Несмотря на то, что этот метод всегда документировался как метод-корутина, в версиях до Python 3.7 он возвращал
Future. Начиная с Python 3.7, это метод-корутина.
-
coroutine loop.sock_recv_into(sock, buf) -
Принимает данные из sock в буфер buf. Моделируется по блокирующему методу
socket.recv_into().Возвращает количество байтов, записанных в буфер.
sock должен быть сокетом в режиме без ожидания.
Добавлен в версии 3.7.
-
coroutine loop.sock_recvfrom(sock, bufsize) -
Принимает дейтаграмму до bufsize байтов из sock. Асинхронная версия
socket.recvfrom().Возвращает кортеж (полученные данные, адрес удаленного узла).
sock должен быть сокетом в режиме без ожидания.
Добавлен в версии 3.11.
-
coroutine loop.sock_recvfrom_into(sock, buf, nbytes=0) -
Принимает дейтаграмму до nbytes байтов из sock в buf. Асинхронная версия
socket.recvfrom_into().Возвращает кортеж (количество полученных байтов, адрес удаленного узла).
sock должен быть сокетом в режиме без ожидания.
Добавлен в версии 3.11.
-
coroutine loop.sock_sendall(sock, data) -
Отправляет data на сокет sock. Асинхронная версия
socket.sendall().Этот метод продолжает отправлять данные в сокет, пока все данные в data не будут отправлены или не произойдет ошибка.
Noneвозвращается при успехе. При ошибке генерируется исключение. Кроме того, нет способа определить, сколько данных, если таковые имеются, было успешно обработано принимающей стороной подключения.sock должен быть сокетом в режиме без ожидания.
Изменено в версии 3.7: Несмотря на то, что метод всегда документировался как метод-корутина, до Python 3.7 он возвращал
Future. Начиная с Python 3.7, это метод-корутина.
-
coroutine loop.sock_sendto(sock, data, address) -
Отправляет дейтаграмму из sock на address. Асинхронная версия
socket.sendto().Возвращает количество отправленных байтов.
sock должен быть сокетом в режиме без ожидания.
Добавлен в версии 3.11.
-
coroutine loop.sock_connect(sock, address) -
Подключает sock к удаленному сокету по адресу address.
Асинхронная версия
socket.connect().sock должен быть сокетом в режиме без ожидания.
Изменено в версии 3.5.2:
addressбольше не требует разрешения.sock_connectпопытается проверить, уже ли разрешен address, вызвавsocket.inet_pton(). Если нет, будет использованloop.getaddrinfo()для разрешения address.См. также
-
coroutine loop.sock_accept(sock) -
Принимает подключение. Моделируется по блокирующему методу
socket.accept().Сокет должен быть привязан к адресу и ожидать подключений. Результат — пара
(conn, address), где conn — новый объект сокета, используемый для отправки и приема данных по подключению, и address — адрес, привязанный к сокету на другом конце подключения.sock должен быть сокетом в режиме без ожидания.
Изменено в версии 3.7: Несмотря на то, что метод всегда документировался как метод-корутина, до Python 3.7 он возвращал
Future. Начиная с Python 3.7, это метод-корутина.См. также
-
coroutine loop.sock_sendfile(sock, file, offset=0, count=None, *, fallback=True) -
Отправляет файл, используя высокопроизводительный
os.sendfile, если это возможно. Возвращает общее количество отправленных байтов.Асинхронная версия
socket.sendfile().sock должен быть сокетом в режиме без ожидания типа
socket.SOCK_STREAMsocket.file должен быть объектом обычного файла, открытым в двоичном режиме.
offset указывает, с какого места начать чтение файла. Если указано, count — общее количество байтов для передачи, а не отправка файла до достижения EOF. Положение файла всегда обновляется, даже если этот метод генерирует ошибку, и
file.tell()можно использовать для получения фактического количества отправленных байтов.fallback, при значении
True, заставляет asyncio вручную читать и отправлять файл, когда платформа не поддерживает вызов sendfile (например, Windows или SSL-сокеты в Unix).Вызывает
SendfileNotAvailableError, если система не поддерживает вызов sendfile, а fallback имеет значениеFalse.sock должен быть сокетом в режиме без ожидания.
Добавлен в версии 3.7.
DNS
-
coroutine loop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0) -
Асинхронная версия
socket.getaddrinfo().
-
coroutine loop.getnameinfo(sockaddr, flags=0) -
Асинхронная версия
socket.getnameinfo().
Примечание
И getaddrinfo, и getnameinfo внутри используют свои синхронные версии через исполняемый модуль пула потоков по умолчанию цикла. Когда этот исполняемый модуль перегружен, эти методы могут испытывать задержки, что могут быть ошибочно приняты за увеличение таймаутов в библиотеках сетевого программирования более высокого уровня. Для снижения этого эффекта, рассмотрите возможность использования настраиваемого исполняемого модуля для других пользовательских задач или установку исполняемого модуля по умолчанию с большим количеством потоков.
Изменено в версии 3.7: И методы getaddrinfo, и getnameinfo всегда были документированы как возвращающие корутины, но до Python 3.7 они на самом деле возвращали объекты asyncio.Future. Начиная с Python 3.7, оба метода являются корутинами.
Работа с каналами
-
coroutine loop.connect_read_pipe(protocol_factory, pipe) -
Регистрирует конец чтения канала pipe в цикле событий.
protocol_factory должно быть вызываемым объектом, возвращающим реализацию протокола asyncio-протокола.
pipe — это объект, подобный файлу объекту-подобному файлу.
Возвращает пару
(transport, protocol), где transport поддерживает интерфейсReadTransport, а protocol — объект, созданный protocol_factory.В цикле событий типа
SelectorEventLoopканал pipe переводится в режим «без блокировки».
-
coroutine loop.connect_write_pipe(protocol_factory, pipe) -
Регистрирует конец записи канала pipe в цикле событий.
protocol_factory должно быть вызываемым объектом, возвращающим реализацию протокола asyncio-протокола.
pipe — это объект, подобный файлу.
Возвращает пару
(transport, protocol), где transport поддерживает интерфейсWriteTransport, а protocol — объект, созданный protocol_factory.В цикле событий типа
SelectorEventLoopканал pipe переводится в режим «без блокировки».
Примечание
SelectorEventLoop не поддерживает указанные методы в Windows. Для Windows используйте ProactorEventLoop.
См. также
Сигналы Unix
-
loop.add_signal_handler(signum, callback, *args) -
Устанавливает callback в качестве обработчика сигнала signum.
Обработчик вызывается циклом loop совместно с другими очередями вызовов и исполняемыми корутинами этого цикла событий. В отличие от обработчиков сигналов, зарегистрированных с помощью
signal.signal(), обработчик, зарегистрированный с помощью этой функции, может взаимодействовать с циклом событий.Вызывает исключение
ValueError, если номер сигнала недопустим или не может быть перехвачен. Вызывает исключениеRuntimeError, если возникла проблема с настройкой обработчика.Используйте
functools.partial()для передачи аргументов по имени в callback.Как и
signal.signal(), эта функция должна вызываться в основном потоке.
-
loop.remove_signal_handler(sig) -
Удаляет обработчик сигнала sig.
Возвращает
Trueесли обработчик сигнала был удалён, илиFalseесли обработчик сигнала не был установлен для данного сигнала.Доступность: Unix.
См. также
Модуль signal.
Выполнение кода в пулах потоков или процессов
-
awaitable loop.run_in_executor(executor, func, *args) -
Вызывает func в указанном исполнителе.
Аргумент executor должен быть экземпляром
concurrent.futures.Executor. Используется исполнителем по умолчанию, если executor равенNone. Исполнитель по умолчанию может быть установлен с помощьюloop.set_default_executor(), в противном случае,concurrent.futures.ThreadPoolExecutorбудет инициализироваться лениво и использоватьсяrun_in_executor()по мере необходимости.Пример:
import asyncio import concurrent.futures def blocking_io(): # File operations (such as logging) can block the # event loop: run them in a thread pool. with open('/dev/urandom', 'rb') as f: return f.read(100) def cpu_bound(): # CPU-bound operations will block the event loop: # in general it is preferable to run them in a # process pool. return sum(i * i for i in range(10 ** 7)) async def main(): loop = asyncio.get_running_loop() ## Options: # 1. Run in the default loop's executor: result = await loop.run_in_executor( None, blocking_io) print('default thread pool', result) # 2. Run in a custom thread pool: with concurrent.futures.ThreadPoolExecutor() as pool: result = await loop.run_in_executor( pool, blocking_io) print('custom thread pool', result) # 3. Run in a custom process pool: with concurrent.futures.ProcessPoolExecutor() as pool: result = await loop.run_in_executor( pool, cpu_bound) print('custom process pool', result) if __name__ == '__main__': asyncio.run(main())Обратите внимание, что запуск кода в отдельном потоке (
if __name__ == '__main__') требуется для варианта 3 из-за особенностей модуляmultiprocessing, используемогоProcessPoolExecutor. Смотрите Безопасный импорт основного модуля.Этот метод возвращает объект
asyncio.Future.Используйте
functools.partial()для передачи аргументов по имени в func.Изменено в версии 3.5.3:
loop.run_in_executor()больше не настраиваетmax_workersисполнителя пула потоков, вместо этого оставляя это задачей самому исполнителю пула потоков (ThreadPoolExecutor).
-
loop.set_default_executor(executor) -
Устанавливает executor в качестве исполнителя по умолчанию, используемого
run_in_executor(). executor должен быть экземпляромThreadPoolExecutor.Изменено в версии 3.11: executor должен быть экземпляром
ThreadPoolExecutor.
Обработка ошибок API
Позволяет настроить обработку исключений в цикле событий.
-
loop.set_exception_handler(handler) -
Устанавливает handler в качестве нового обработчика исключений цикла событий.
Если handler равен
None, будет установлен обработчик исключений по умолчанию. В противном случае, handler должен быть вызываемым объектом с сигнатурой, соответствующей(loop, context), гдеloop— ссылка на активный цикл событий, аcontext— объектdict, содержащий сведения об исключении (см. документациюcall_exception_handler()для подробностей о контексте).Если обработчик вызывается от имени
TaskилиHandle, он выполняется вcontextvars.Contextэтой задачи или обработчика.Изменено в версии 3.12: Обработчик может вызываться в
Contextзадачи или обработчика, где возникло исключение.
-
loop.get_exception_handler() -
Возвращает текущий обработчик исключений или
None, если пользовательский обработчик исключений не был установлен.Добавлен в версии 3.5.2.
-
loop.default_exception_handler(context) -
Обработчик исключений по умолчанию.
Вызывается при возникновении исключения, если обработчик исключений не задан. Может вызываться пользовательским обработчиком исключений, который хочет использовать поведение обработчика по умолчанию.
Параметр context имеет то же значение, что и в
call_exception_handler().
-
loop.call_exception_handler(context) -
Вызывает текущий обработчик исключений цикла событий.
context — объект
dict, содержащий следующие ключи (в будущих версиях Python могут быть добавлены новые ключи):- ‘message’: Сообщение об ошибке;
- ‘exception’ (необязательно): Объект исключения;
- ‘future’ (необязательно): Экземпляр
asyncio.Future; - ‘task’ (необязательно): Экземпляр
asyncio.Task; - ‘handle’ (необязательно): Экземпляр
asyncio.Handle; - ‘protocol’ (необязательно): Экземпляр Протокола;
- ‘transport’ (необязательно): Экземпляр Транспортного средства;
- ‘socket’ (необязательно): Экземпляр
socket.socket; -
- ‘asyncgen’ (необязательно): Асинхронный генератор, который вызвал
-
исключение.
Примечание
Этот метод не должен переопределяться в циклах событий, наследуемых от базового класса. Для настройки обработки исключений используйте метод
set_exception_handler().
Включение отладочного режима
-
loop.get_debug() -
Получение отладочного режима (
bool) цикла событий.Значение по умолчанию —
True, если переменная окруженияPYTHONASYNCIODEBUGустановлена непустой строкой,Falseв противном случае.
-
loop.set_debug(enabled: bool) -
Установка отладочного режима цикла событий.
Изменено в версии 3.7: Теперь также можно использовать новый Режим разработки Python для включения отладочного режима.
-
loop.slow_callback_duration -
Это атрибут, который можно использовать для установки минимальной длительности выполнения в секундах, которая считается «медленной». В отладочном режиме «медленные» обратные вызовы регистрируются.
Значение по умолчанию — 100 миллисекунд.
См. также
Режим отладки asyncio.
Запуск дочерних процессов
Методы, описанные в этом подразделе, являются низкоуровневыми. В обычном коде async/await следует использовать высокоуровневые функции asyncio.create_subprocess_shell() и asyncio.create_subprocess_exec() для удобства.
Примечание
В Windows, по умолчанию, цикл событий ProactorEventLoop поддерживает дочерние процессы, в то время как SelectorEventLoop их не поддерживает. Подробности см. в разделе Поддержка дочерних процессов в Windows.
-
coroutine loop.subprocess_exec(protocol_factory, *args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) -
Создаёт дочерний процесс по одному или нескольким строковым аргументам, указанным в args.
args должно быть списком строк, представленных:
-
str; - или
bytes, закодированными в кодировку файловой системы.
Первая строка задаёт исполняемый файл программы, а последующие строки — аргументы. Вместе, строковые аргументы образуют
argvпрограммы.Это аналогично классу
subprocess.Popenстандартной библиотеки, вызываемому сshell=Falseи списком строк в качестве первого аргумента; однако, гдеPopenпринимает один аргумент — список строк, subprocess_exec принимает несколько строковых аргументов.protocol_factory должно быть вызываемой функцией, возвращающей подкласс класса
asyncio.SubprocessProtocol.Другие параметры:
-
stdin может быть любым из следующих:
- объект типа «поток»
- существующий дескриптор файла (положительное целое число), например, созданный с помощью
os.pipe() - константа
subprocess.PIPE(по умолчанию), которая создаст новую трубу и соединит её, - значение
None, которое заставит дочерний процесс унаследовать дескриптор файла от текущего процесса - константа
subprocess.DEVNULL, которая указывает на использование специального файлаos.devnull
-
stdout может быть любым из следующих:
- объект типа «поток»
- константа
subprocess.PIPE(по умолчанию), которая создаст новую трубу и соединит её, - значение
None, которое заставит дочерний процесс унаследовать дескриптор файла от текущего процесса - константа
subprocess.DEVNULL, которая указывает на использование специального файлаos.devnull
-
stderr может быть любым из следующих:
- объект типа «поток»
- константа
subprocess.PIPE(по умолчанию), которая создаст новую трубу и соединит её, - значение
None, которое заставит дочерний процесс унаследовать дескриптор файла от текущего процесса - константа
subprocess.DEVNULL, которая указывает на использование специального файлаos.devnull - константа
subprocess.STDOUT, которая соединит поток стандартной ошибки с потоком стандартного вывода процесса
-
Все остальные ключевые аргументы передаются в
subprocess.Popenбез интерпретации, за исключением bufsize, universal_newlines, shell, text, encoding и errors, которые вообще не должны указываться.API дочерних процессов
asyncioне поддерживает декодирование потоков как текста.bytes.decode()может быть использован для преобразования байтовых данных, возвращённых потоком, в текст.
Если объект типа «поток», переданный в качестве stdin, stdout или stderr, представляет трубу, то другая сторона этой трубы должна быть зарегистрирована с помощью
connect_write_pipe()илиconnect_read_pipe()для использования с циклом событий.См. конструктор класса
subprocess.Popenдля документации по другим аргументам.Возвращает пару
(transport, protocol), где transport соответствует базовому классуasyncio.SubprocessTransport, а protocol — объекту, созданному с помощью protocol_factory. -
-
coroutine loop.subprocess_shell(protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) -
Создаёт дочерний процесс из cmd, которое может быть строкой
strилиbytes, закодированной в кодировку файловой системы, используя синтаксис «shell» платформы.Это аналогично классу
subprocess.Popenстандартной библиотеки, вызываемому сshell=True.protocol_factory должно быть вызываемой функцией, возвращающей подкласс класса
SubprocessProtocol.См.
subprocess_exec()для получения дополнительной информации об оставшихся аргументах.Возвращает пару
(transport, protocol), где transport соответствует базовому классуSubprocessTransport, а protocol — объекту, созданному с помощью protocol_factory.
Примечание
Приложения несут ответственность за обеспечение правильного экранирования пробелов и специальных символов, чтобы избежать уязвимостей shell injection. Функция shlex.quote() может быть использована для правильного экранирования пробелов и специальных символов в строках, которые будут использоваться для построения команд shell.
Обработчики обратных вызовов
-
class asyncio.Handle -
Объект-обёртку для обратного вызова, возвращаемый функциями
loop.call_soon()иloop.call_soon_threadsafe().-
get_context() -
Возвращает объект
contextvars.Context, связанный с обработчиком.Добавлена в версии 3.12.
-
cancel() -
Отменить обратный вызов. Если обратный вызов уже был отменён или выполнен, этот метод не оказывает эффекта.
-
cancelled() -
Возвращает
True, если обратный вызов был отменён.Добавлена в версии 3.7.
-
-
class asyncio.TimerHandle -
Объект-обёртку для обратного вызова, возвращаемый функциями
loop.call_later()иloop.call_at().Этот класс является подклассом
Handle.-
when() -
Возвращает время запланированного обратного вызова как значение
floatв секундах.Время является абсолютной меткой времени, используя ту же временную отсылку, что и
loop.time().Добавлена в версии 3.7.
-
Объекты сервера
Объекты сервера создаются функциями loop.create_server(), loop.create_unix_server(), start_server() и start_unix_server().
Не следует создавать экземпляры класса Server напрямую.
-
class asyncio.Server -
Объекты сервера являются асинхронными контекстными менеджерами. При использовании в блоке
async withгарантируется, что объект сервера закрыт и не принимает новые подключения, когда завершается блокasync with:srv = await loop.create_server(...) async with srv: # some code # At this point, srv is closed and no longer accepts new connections.Изменено в версии 3.7: Объект сервера является асинхронным контекстным менеджером начиная с Python 3.7.
Изменено в версии 3.11: Этот класс был открыто доступен как
asyncio.Serverв Python 3.9.11, 3.10.3 и 3.11.-
close() -
Остановка обслуживания: закрытие сокетов прослушивания и установка атрибута
socketsвNone.Сокеты, представляющие существующие входящие подключения клиентов, остаются открытыми.
Сервер закрывается асинхронно; используйте корутину
wait_closed()для ожидания закрытия сервера (и завершения всех активных подключений).
-
get_loop() -
Возвращает цикл событий, связанный с объектом сервера.
Добавлен в версии 3.7.
-
coroutine start_serving() -
Начать прием подключений.
Этот метод идемпотентен, поэтому его можно вызывать, когда сервер уже обслуживает подключения.
Ключевое слово-только параметр start_serving для
loop.create_server()иasyncio.start_server()позволяет создать объект сервера, который изначально не принимает подключения. В этом случаеServer.start_serving(), илиServer.serve_forever()можно использовать для начала приема подключений сервером.Добавлен в версии 3.7.
-
coroutine serve_forever() -
Начать прием подключений до отмены корутины. Отмена задачи
serve_foreverприводит к закрытию сервера.Этот метод можно вызывать, если сервер уже принимает подключения. Только одна задача
serve_foreverможет существовать на один объект Server.Пример:
async def client_connected(reader, writer): # Communicate with the client with # reader/writer streams. For example: await reader.readline() async def main(host, port): srv = await asyncio.start_server( client_connected, host, port) await srv.serve_forever() asyncio.run(main('127.0.0.1', 0))Добавлен в версии 3.7.
-
is_serving() -
Возвращает
True, если сервер принимает новые подключения.Добавлен в версии 3.7.
-
coroutine wait_closed() -
Ожидание завершения метода
close()и завершения всех активных подключений.
-
sockets -
Список объектов, подобных сокетам,
asyncio.trsock.TransportSocket, на которых сервер прослушивает подключения.Изменено в версии 3.7: До Python 3.7
Server.socketsвозвращал внутренний список сокетов сервера напрямую. В 3.7 возвращается копия этого списка.
-
Реализации циклов событий
В asyncio используются две разные реализации циклов событий: SelectorEventLoop и ProactorEventLoop.
По умолчанию asyncio настраивается на использование SelectorEventLoop на Unix и ProactorEventLoop на Windows.
-
class asyncio.SelectorEventLoop -
Цикл событий, основанный на модуле
selectors.Использует наиболее эффективный селектор, доступный для данной платформы. Также возможно вручную настроить конкретную реализацию селектора:
import asyncio import selectors class MyPolicy(asyncio.DefaultEventLoopPolicy): def new_event_loop(self): selector = selectors.SelectSelector() return asyncio.SelectorEventLoop(selector) asyncio.set_event_loop_policy(MyPolicy())Доступность: Unix, Windows.
-
class asyncio.ProactorEventLoop -
Цикл событий для Windows, использующий «порты завершения операций ввода/вывода» (IOCP).
Доступность: Windows.
-
class asyncio.AbstractEventLoop -
Абстрактный базовый класс для циклов событий, совместимых с asyncio.
В разделе Методы цикла событий перечислены все методы, которые должна определить альтернативная реализация
AbstractEventLoop.
Примеры
Обратите внимание, что все примеры в этом разделе намеренно демонстрируют использование API низкоуровневого цикла событий, таких как loop.run_forever() и loop.call_soon(). Современные приложения asyncio редко требуют написания кода таким образом; рассмотрите использование высокоуровневых функций, таких как asyncio.run().
Привет, мир с call_soon()
Пример использования метода loop.call_soon() для планирования обратного вызова. Обратный вызов отображает "Hello World" и затем останавливает цикл событий:
import asyncio
def hello_world(loop):
"""A callback to print 'Hello World' and stop the event loop"""
print('Hello World')
loop.stop()
loop = asyncio.new_event_loop()
# Schedule a call to hello_world()
loop.call_soon(hello_world, loop)
# Blocking call interrupted by loop.stop()
try:
loop.run_forever()
finally:
loop.close()
См. также
Аналогичный пример «Привет, мир» Привет, мир, созданный с помощью сопрограммы и функции run().
Отображение текущей даты с помощью call_later()
Пример обратного вызова, отображающего текущую дату каждую секунду. Обратный вызов использует метод loop.call_later() для повторного планирования себя через 5 секунд, а затем останавливает цикл событий:
import asyncio
import datetime
def display_date(end_time, loop):
print(datetime.datetime.now())
if (loop.time() + 1.0) < end_time:
loop.call_later(1, display_date, end_time, loop)
else:
loop.stop()
loop = asyncio.new_event_loop()
# Schedule the first call to display_date()
end_time = loop.time() + 5.0
loop.call_soon(display_date, end_time, loop)
# Blocking call interrupted by loop.stop()
try:
loop.run_forever()
finally:
loop.close()
См. также
Аналогичный пример текущей даты, созданный с помощью сопрограммы и функции run().
Отслеживание дескриптора файла на события чтения
Ожидание, пока дескриптор файла получит данные, используя метод loop.add_reader(), а затем закрытие цикла событий:
import asyncio
from socket import socketpair
# Create a pair of connected file descriptors
rsock, wsock = socketpair()
loop = asyncio.new_event_loop()
def reader():
data = rsock.recv(100)
print("Received:", data.decode())
# We are done: unregister the file descriptor
loop.remove_reader(rsock)
# Stop the event loop
loop.stop()
# Register the file descriptor for read event
loop.add_reader(rsock, reader)
# Simulate the reception of data from the network
loop.call_soon(wsock.send, 'abc'.encode())
try:
# Run the event loop
loop.run_forever()
finally:
# We are done. Close sockets and the event loop.
rsock.close()
wsock.close()
loop.close()
См. также
- Аналогичный пример примера с использованием транспортов, протоколов и метода
loop.create_connection(). - Еще один аналогичный пример примера с использованием высокоуровневой функции
asyncio.open_connection()и потоков.
Установить обработчики сигналов для SIGINT и SIGTERM
(Этот signals пример работает только на Unix.)
Регистрация обработчиков сигналов SIGINT и SIGTERM с помощью метода loop.add_signal_handler():
import asyncio
import functools
import os
import signal
def ask_exit(signame, loop):
print("got signal %s: exit" % signame)
loop.stop()
async def main():
loop = asyncio.get_running_loop()
for signame in {'SIGINT', 'SIGTERM'}:
loop.add_signal_handler(
getattr(signal, signame),
functools.partial(ask_exit, signame, loop))
await asyncio.sleep(3600)
print("Event loop running for 1 hour, press Ctrl+C to interrupt.")
print(f"pid {os.getpid()}: send SIGINT or SIGTERM to exit.")
asyncio.run(main())
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/asyncio-eventloop.html