Цикл обработки событий

Исходный код: Lib/asyncio/events.py, Lib/asyncio/base_events.py


P

P

:func:`asyncio.run`P

Получение события

Для получения, установки или создания цикла обработки событий можно использовать следующие низкоуровневые функции:

asyncio.get_running_loop()

Для получения, установки или создания цикла обработки событий можно использовать следующие низкоуровневые функции:

:exc:`RuntimeError`Для получения, установки или создания цикла обработки событий можно использовать следующие низкоуровневые функции:

Для получения, установки или создания цикла обработки событий можно использовать следующие низкоуровневые функции:

Добавлено в версии 3.7.

asyncio.get_event_loop()

Для получения, установки или создания цикла обработки событий можно использовать следующие низкоуровневые функции:

Для получения, установки или создания цикла обработки событий можно использовать следующие низкоуровневые функции:

``get_event_loop_policy().get_event_loop()``Для получения, установки или создания цикла обработки событий можно использовать следующие низкоуровневые функции:

get_running_loop`Для получения, :func:`get_event_loop() установки или создания цикла обработки событий можно использовать следующие низкоуровневые функции:

:func:`asyncio.run`Для получения, установки или создания цикла обработки событий можно использовать следующие низкоуровневые функции:

Примечание

В версиях Python 3.10.0-3.10.8 и 3.11.0 эта функция (и другие функции, которые используют ее неявно) выдавали DeprecationWarning, если не было запущенного цикла обработки событий, даже если текущий цикл был задан в политике. В версиях Python 3.10.9, 3.11.1 и 3.12 они выдают DeprecationWarning, если не запущен цикл обработки событий и не задан текущий цикл. В некоторых будущих версиях Python это станет ошибкой.

asyncio.set_event_loop(loop)

Установите loop в качестве текущего цикла обработки событий для текущего потока операционной системы.

asyncio.new_event_loop()

Установите loop в качестве текущего цикла обработки событий для текущего потока операционной системы.

Обратите внимание, что поведение функций get_event_loop(), set_event_loop(), и new_event_loop() может быть изменено с помощью setting a custom event loop policy.

C

Эта страница документации содержит следующие разделы:

Цикл обработки событий

Цикл обработки событий

Запуск и остановка цикла

loop.run_until_complete(future)

Выполняйте до тех пор, пока не завершится future (экземпляр Future).

Если аргументом является coroutine object, то он неявно запланирован для запуска как asyncio.Task.

Если аргументом является , то он неявно запланирован для запуска как .

loop.run_forever()

Запускайте цикл обработки событий до тех пор, пока не будет вызван stop().

Если stop() вызывается до run_forever(), цикл опрашивает селектор ввода-вывода один раз с нулевым таймаутом, запускает все обратные вызовы, запланированные в ответ на события ввода-вывода (и те, которые уже были запланированы), а затем завершает работу.

Если stop() вызывается до run_forever(), цикл run_forever() опрашивает run_until_complete() селектор ввода-вывода один раз с нулевым таймаутом, запускает все обратные вызовы, запланированные в ответ на события ввода-вывода (и те, которые уже были запланированы), а затем завершает работу.

loop.stop()

Если вызывается до , цикл опрашивает селектор ввода-вывода один раз с нулевым таймаутом, запускает все обратные вызовы, запланированные в ответ на события ввода-вывода (и те, которые уже были запланированы), а затем завершает работу.

loop.is_running()

Если True вызывается до , цикл опрашивает селектор ввода-вывода один раз с нулевым таймаутом, запускает все обратные вызовы, запланированные в ответ на события ввода-вывода (и те, которые уже были запланированы), а затем завершает работу.

loop.is_closed()

Возвращает True, если цикл обработки событий был закрыт.

loop.close()

Возвращает , если цикл обработки событий был закрыт.

Цикл не должен выполняться при вызове этой функции. Все ожидающие обратные вызовы будут отброшены.

Цикл не должен выполняться при вызове этой функции. Все ожидающие обратные вызовы будут отброшены.

Этот метод является идемпотентным и необратимым. После завершения цикла обработки событий не следует вызывать никакие другие методы.

coroutine loop.shutdown_asyncgens()

Запланируйте закрытие всех открытых в данный момент объектов asynchronous generator с помощью вызова aclose(). После вызова этого метода цикл обработки событий выдаст предупреждение, если будет запущен новый асинхронный генератор. Это следует использовать для надежного завершения работы всех запланированных асинхронных генераторов.

Обратите внимание, что нет необходимости вызывать эту функцию, когда используется asyncio.run().

Пример:

try:
    loop.run_forever()
finally:
    loop.run_until_complete(loop.shutdown_asyncgens())
    loop.close()

Добавлено в версии 3.6.

coroutine loop.shutdown_default_executor()

Запланируйте закрытие исполнителя по умолчанию и дождитесь, пока он присоединится ко всем потокам в ThreadPoolExecutor. Как только этот метод будет вызван, использование исполнителя по умолчанию с loop.run_in_executor() вызовет RuntimeError.

Примечание

Не вызывайте этот метод при использовании asyncio.run(), так как последний автоматически завершает работу исполнителя по умолчанию.

Добавлено в версии 3.9.

Планирование обратных вызовов

loop.call_soon(callback, *args, context=None)

Запланируйте вызов обратного вызова callback с аргументами args на следующей итерации цикла обработки событий.

Возвращает экземпляр asyncio.Handle, который позже может быть использован для отмены обратного вызова.

Обратные вызовы вызываются в том порядке, в котором они зарегистрированы. Каждый обратный вызов будет вызван ровно один раз.

Необязательный аргумент context, содержащий только ключевое слово, указывает пользовательское значение contextvars.Context для выполнения обратного вызова. Обратные вызовы используют текущий контекст, если контекст не указан.

В отличие от call_soon_threadsafe(), этот метод не является потокобезопасным.

loop.call_soon_threadsafe(callback, *args, context=None)

Потокобезопасный вариант call_soon(). При планировании обратных вызовов из другого потока необходимо использовать эту функцию, поскольку call_soon() не является потокобезопасной.

Вызывает RuntimeError при вызове в цикле, который был закрыт. Это может произойти во вторичном потоке, когда основное приложение завершает работу.

Смотрите раздел concurrency and multithreading документации.

Изменено в версии 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)

Запланируйте обратный вызов, который будет вызван после заданного количества задержек в секундах (может быть как int, так и float).

Возвращается экземпляр asyncio.TimerHandle, который может быть использован для отмены обратного вызова.

обратный вызов будет вызван ровно один раз. Если два обратных вызова запланированы на одно и то же время, порядок их вызова не определен.

Необязательные позиционные аргументы будут переданы в обратный вызов при его вызове. Если вы хотите, чтобы обратный вызов вызывался с аргументами ключевого слова, используйте functools.partial().

Необязательный аргумент context, содержащий только ключевое слово, позволяет указать пользовательский contextvars.Context для выполнения обратного вызова. Если контекст не указан, используется текущий контекст.

Изменено в версии 3.7: Был добавлен параметр context, предназначенный только для ключевых слов. Более подробную информацию смотрите в разделе PEP 567.

Изменено в версии 3.8: В Python 3.7 и более ранних версиях с реализацией цикла обработки событий по умолчанию задержка не могла превышать одного дня. Это было исправлено в Python 3.8.

loop.call_at(when, callback, *args, context=None)

Запланируйте обратный вызов на заданную абсолютную временную метку when (int или float), используя ту же временную привязку, что и 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 и более ранних версиях тайм-ауты (относительная задержка или абсолютная при) не должны превышать одного дня. Это было исправлено в Python 3.8.

См.также

Функция asyncio.sleep().

Создание функций и задач

loop.create_future()

Создайте объект asyncio.Future, подключенный к циклу обработки событий.

Это предпочтительный способ создания Futures в asyncio. Это позволяет сторонним циклам обработки событий предоставлять альтернативные реализации объекта Future (с лучшей производительностью или инструментарием).

Добавлено в версии 3.5.2.

loop.create_task(coro, *, name=None, context=None)

Запланируйте выполнение coroutine 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().

Установите фабрику задач, которая будет использоваться None (loop, coro, context=None) 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)

Откройте потоковое транспортное соединение по заданному адресу, указанному в параметрах хост и порт.

Семейство сокетов может быть либо AF_INET, либо AF_INET6 в зависимости от host (или аргумента family, если он указан).

Тип сокета будет SOCK_STREAM.

protocol_factory должен быть вызываемым, возвращающим реализацию asyncio protocol.

Этот метод попытается установить соединение в фоновом режиме. В случае успеха он возвращает пару (transport, protocol).

Хронологический обзор основной операции выглядит следующим образом:

  1. Соединение установлено, и для него создается transport.

  2. protocol_factory вызывается без аргументов и, как ожидается, вернет экземпляр protocol.

  3. Экземпляр протокола соединяется с транспортным средством путем вызова его метода connection_made().

  4. В случае успешного завершения возвращается кортеж (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() для разрешения хоста. Если они указаны, все они должны быть целыми числами из соответствующих socket констант модуля.

  • happy_eyeballs_delay, если задано, включает функцию «счастливого просмотра» для этого соединения. Это должно быть число с плавающей запятой, представляющее количество времени в секундах, в течение которого необходимо дождаться завершения попытки подключения, прежде чем начать следующую попытку параллельно. Это и есть «Задержка попытки подключения», как определено в RFC 8305. Разумным значением по умолчанию, рекомендованным RFC, является 0.25 (250 миллисекунд).

  • чередование управляет переупорядочиванием адресов, когда имя хоста преобразуется в несколько 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 (по умолчанию).

Изменено в версии 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.

См.также

Функция open_connection() является высокоуровневым альтернативным API. Она возвращает пару (StreamReader, StreamWriter), которые могут быть использованы непосредственно в асинхронном/ожидающем коде.

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 должен быть вызываемым, возвращающим реализацию protocol.

В случае успеха возвращается кортеж из (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() для разрешения хоста. Если они указаны, все они должны быть целыми числами из соответствующих socket констант модуля.

  • reuse_port указывает ядру разрешить привязку этой конечной точки к тому же порту, к которому привязаны другие существующие конечные точки, при условии, что все они установили этот флаг при создании. Эта опция не поддерживается в Windows и некоторых Unix-версиях. Если константа socket.SO_REUSEPORT не определена, то эта возможность не поддерживается.

  • allow_broadcast указывает ядру разрешить этой конечной точке отправлять сообщения на широковещательный адрес.

  • sock может быть дополнительно указан для использования ранее существовавшего, уже подключенного объекта socket.socket, который будет использоваться транспортным средством. Если указано, то local_addr и remote_addr должны быть опущены (должно быть None).

    Примечание

    Аргумент sock передает права собственности на сокет созданному транспортному средству. Чтобы закрыть сокет, вызовите метод close(), используемый транспортным средством.

Смотрите примеры UDP echo client protocol и UDP echo server protocol.

Изменено в версии 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 вызовет исключение.

Когда несколько процессов с разными UID назначают сокетам одинаковый адрес UDP-сокета с SO_REUSEADDR, входящие пакеты могут случайным образом распределяться между сокетами.

Для поддерживаемых платформ в качестве замены аналогичной функциональности можно использовать reuse_port. Вместо reuse_port используется socket.SO_REUSEPORT, что, в частности, предотвращает назначение сокетами одного и того же адреса сокета процессам с разными идентификаторами UID.

Изменено в версии 3.11: Параметр reuse_address, отключенный начиная с версий Python 3.8.1, 3.7.6 и 3.6.10, был полностью удален.

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() для получения информации об аргументах этого метода.

Availability: Unix.

Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout. Параметром path теперь может быть path-like object.

Изменено в версии 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), прослушивающий порт адреса хоста.

Возвращает объект Server.

Аргументы:

  • protocol_factory должен быть вызываемым, возвращающим реализацию protocol.

  • Параметру host можно присвоить несколько типов, которые определяют, где сервер будет осуществлять прослушивание:

    • Если host является строкой, то TCP-сервер привязан к одному сетевому интерфейсу, указанному в host.

    • Если host представляет собой последовательность строк, то TCP-сервер привязан ко всем сетевым интерфейсам, указанным в этой последовательности.

    • Если host является пустой строкой или None, предполагаются все интерфейсы и будет возвращен список из нескольких сокетов (скорее всего, один для IPv4, а другой для IPv6).

  • Параметр port может быть установлен таким образом, чтобы указать, какой порт должен прослушиваться сервером. Если 0 или None (по умолчанию), будет выбран случайный неиспользуемый порт (обратите внимание, что если host разрешает использование нескольких сетевых интерфейсов, для каждого интерфейса будет выбран другой случайный порт).

  • family может быть установлено в значение socket.AF_INET или AF_INET6, чтобы заставить сокет использовать IPv4 или IPv6. Если параметр не задан, то семейство будет определяться по имени хоста (по умолчанию используется AF_UNSPEC).

  • flags - это битовая маска для getaddrinfo().

  • при необходимости можно указать sock, чтобы использовать уже существующий объект socket. Если указано, то host и port указывать не нужно.

    Примечание

    Аргумент sock передает право собственности на сокет созданному серверу. Чтобы закрыть сокет, вызовите серверный метод close().

  • невыполненная работа - это максимальное количество подключений в очереди, переданных в listen() (по умолчанию 100).

  • ssl может быть установлен в качестве экземпляра SSLContext, чтобы включить TLS для принятых подключений.

  • reuse_address указывает ядру повторно использовать локальный сокет в состоянии TIME_WAIT, не дожидаясь истечения его естественного тайм-аута. Если не указано, то в Unix автоматически устанавливается значение True.

  • 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, которые можно использовать в асинхронном/ожидающем коде.

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() для получения информации об аргументах этого метода.

Availability: 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 должен быть вызываемым, возвращающим реализацию protocol.

  • 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(), если таковой имеется.

файл должен быть обычным файловым объектом, открытым в двоичном режиме.

offset указывает, с чего следует начать чтение файла. Если указано, count - это общее количество байт, которое необходимо передать, в отличие от отправки файла до достижения EOF. Позиция файла всегда обновляется, даже если этот метод выдает ошибку, и file.tell() можно использовать для получения фактического количества отправленных байт.

fallback set to True makes asyncio to manually read and send the file when the platform does not support the sendfile system call (e.g. Windows or SSL socket on Unix).

Поднимите SendfileNotAvailableError, если система не поддерживает системный вызов sendfile и резервный вариант равен 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.

Параметры:

  • экземпляры transport и protocol, которые возвращают такие методы, как create_server() и create_connection().

  • sslcontext: сконфигурированный экземпляр SSLContext.

  • server_side передает True при обновлении соединения на стороне сервера (например, созданного create_server()).

  • server_hostname: задает или переопределяет имя хоста, с которым будет сопоставляться сертификат целевого сервера.

  • ssl_handshake_timeout - это (для TLS-соединения) время в секундах, которое требуется для завершения подтверждения связи по протоколу 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 для чтения и вызовите обратный вызов с указанными аргументами, как только fd станет доступен для чтения.

loop.remove_reader(fd)

Прекратите мониторинг файлового дескриптора fd на предмет доступности для чтения. Возвращает True, если ранее fd отслеживался на предмет чтения.

loop.add_writer(fd, callback, *args)

Начните отслеживать файловый дескриптор fd на предмет доступности для записи и вызовите обратный вызов с указанными аргументами, как только fd станет доступен для записи.

Используйте functools.partial() to pass keyword arguments для обратного вызова.

loop.remove_writer(fd)

Прекратите мониторинг файлового дескриптора fd на предмет доступности для записи. Возвращает True, если ранее fd отслеживался на предмет записи.

Смотрите также раздел Platform Support о некоторых ограничениях этих методов.

Непосредственная работа с объектами сокетов

В целом, реализации протоколов, использующие транспортные 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, это метод async def.

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)

Отправьте данные в сокет sock. Асинхронная версия socket.sendall().

Этот метод продолжает отправку в сокет до тех пор, пока либо не будут отправлены все данные в data, либо не произойдет ошибка. В случае успеха возвращается None. В случае ошибки генерируется исключение. Кроме того, невозможно определить, какой объем данных, если таковые имеются, был успешно обработан принимающей стороной соединения.

sock должен быть неблокирующим разъемом.

Изменено в версии 3.7: Несмотря на то, что этот метод всегда документировался как метод сопрограммы, до версии Python 3.7 он возвращал значение Future. Начиная с версии Python 3.7, это метод async def.

coroutine loop.sock_sendto(sock, data, address)

Отправьте дейтаграмму из sock по адресу. Асинхронная версия socket.sendto().

Возвращает количество отправленных байт.

sock должен быть неблокирующим разъемом.

Добавлено в версии 3.11.

coroutine loop.sock_connect(sock, address)

Подключите sock к удаленной розетке по адресу.

Асинхронная версия socket.connect().

sock должен быть неблокирующим разъемом.

Изменено в версии 3.5.2: address больше не нуждается в разрешении. sock_connect попытается проверить, разрешен ли уже адрес, вызвав socket.inet_pton(). Если нет, то для определения адреса будет использоваться loop.getaddrinfo().

coroutine loop.sock_accept(sock)

Примите соединение. Создан по образцу метода блокировки socket.accept().

Сокет должен быть привязан к определенному адресу и прослушивать соединения. Возвращаемое значение представляет собой пару (conn, address), где conn - это новый объект сокета, используемый для отправки и получения данных по соединению, а address - это адрес, привязанный к сокету на другом конце соединения.

sock должен быть неблокирующим разъемом.

Изменено в версии 3.7: Несмотря на то, что этот метод всегда документировался как метод сопрограммы, до версии Python 3.7 он возвращал значение Future. Начиная с версии Python 3.7, это метод async def.

См.также

loop.create_server() и start_server().

coroutine loop.sock_sendfile(sock, file, offset=0, count=None, *, fallback=True)

Отправьте файл, используя высокопроизводительный os.sendfile, если это возможно. Возвращает общее количество отправленных байт.

Асинхронная версия socket.sendfile().

носок должен быть неблокирующим socket.SOCK_STREAM socket.

файл должен быть обычным файловым объектом, открытым в двоичном режиме.

offset указывает, с чего следует начать чтение файла. Если указано, count - это общее количество байт, которое необходимо передать, в отличие от отправки файла до достижения EOF. Позиция файла всегда обновляется, даже если этот метод выдает ошибку, и file.tell() можно использовать для получения фактического количества отправленных байт.

резервный вариант, если установлено значение True, заставляет asyncio вручную считывать и отправлять файл, когда платформа не поддерживает системный вызов sendfile (например, Windows или SSL-сокет в Unix).

Поднимите SendfileNotAvailableError, если система не поддерживает системный вызов sendfile и резервный вариант равен 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().

Изменено в версии 3.7: Оба метода getaddrinfo и getnameinfo всегда документировались как возвращающие сопрограмму, но до Python 3.7 они, по сути, возвращали asyncio.Future объектов. Начиная с Python 3.7, оба метода являются сопрограммами.

Работа с трубами

coroutine loop.connect_read_pipe(protocol_factory, pipe)

Зарегистрируйте считанный конец канала в цикле обработки событий.

protocol_factory должен быть вызываемым, возвращающим реализацию asyncio protocol.

pipe - это file-like object.

Возвращаемая пара (transport, protocol), где transport поддерживает интерфейс ReadTransport, а protocol является объектом, созданным с помощью protocol_factory.

При использовании SelectorEventLoop цикла обработки событий канал * устанавливается в неблокирующий режим.

coroutine loop.connect_write_pipe(protocol_factory, pipe)

Зарегистрируйте конец записи pipe в цикле обработки событий.

protocol_factory должен быть вызываемым, возвращающим реализацию asyncio protocol.

канал равен file-like object.

Возвращаемая пара (transport, protocol), где transport поддерживает интерфейс WriteTransport, а protocol является объектом, созданным с помощью protocol_factory.

При использовании SelectorEventLoop цикла обработки событий канал * устанавливается в неблокирующий режим.

Примечание

SelectorEventLoop не поддерживает вышеуказанные методы в Windows. Вместо этого используйте ProactorEventLoop для Windows.

См.также

Методы loop.subprocess_exec() и loop.subprocess_shell().

Сигналы Unix

loop.add_signal_handler(signum, callback, *args)

Установите обратный вызов в качестве обработчика для сигнала signum.

Обратный вызов будет вызван loop вместе с другими обратными вызовами в очереди и выполняемыми сопрограммами этого цикла обработки событий. В отличие от обработчиков сигналов, зарегистрированных с помощью signal.signal(), обратному вызову, зарегистрированному с помощью этой функции, разрешено взаимодействовать с циклом обработки событий.

Поднимите ValueError, если номер сигнала неверен или его невозможно поймать. Поднимите RuntimeError, если возникла проблема с настройкой обработчика.

Используйте functools.partial() to pass keyword arguments для обратного вызова.

Как и signal.signal(), эта функция должна быть вызвана в основном потоке.

loop.remove_signal_handler(sig)

Удалите обработчик сигнала sig.

Возвращает True, если обработчик сигнала был удален, или False, если для данного сигнала не был установлен обработчик.

Availability: Unix.

См.также

Модуль signal.

Выполнение кода в пулах потоков или процессов

awaitable loop.run_in_executor(executor, func, *args)

Организуйте вызов func в указанном исполнителе.

Аргументом executor должен быть экземпляр concurrent.futures.Executor. Executor по умолчанию используется, если значение executor равно None.

Пример:

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())

Обратите внимание, что для варианта 3 требуется защита точки входа (if __name__ == '__main__') из-за особенностей multiprocessing, которая используется ProcessPoolExecutor. Смотрите Safe importing of main module.

Этот метод возвращает объект asyncio.Future.

Используйте functools.partial() to pass keyword arguments для функции.

Изменено в версии 3.5.3: loop.run_in_executor() больше не настраивает max_workers созданного им исполнителя пула потоков, вместо этого оставляя за исполнителем пула потоков (ThreadPoolExecutor) возможность установки значения по умолчанию.

loop.set_default_executor(executor)

Установите executor в качестве исполнителя по умолчанию, используемого run_in_executor(). executor должен быть экземпляром ThreadPoolExecutor.

Изменено в версии 3.11: исполнитель должен быть экземпляром ThreadPoolExecutor.

API для обработки ошибок

Позволяет настроить способ обработки исключений в цикле обработки событий.

loop.set_exception_handler(handler)

Установите handler в качестве нового обработчика исключений цикла обработки событий.

Если значение handler равно None, то будет установлен обработчик исключений по умолчанию. В противном случае обработчик должен быть вызываемым с сигнатурой, соответствующей (loop, context), где loop - это ссылка на активный цикл обработки событий, а context - это dict объект, содержащий сведения о исключение (смотрите документацию call_exception_handler() для получения подробной информации о контексте).

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):

  • «сообщение»: сообщение об ошибке;

  • «исключение» (необязательно): объект исключения;

  • «будущее» (необязательно): asyncio.Future экземпляр;

  • «задача» (необязательно): asyncio.Task экземпляр;

  • «дескриптор» (необязательно): asyncio.Handle экземпляр;

  • «протокол» (необязательно): Protocol экземпляр;

  • «транспорт» (необязательно): Transport экземпляр;

  • «сокет» (необязательно): socket.socket экземпляр;

  • „asyncgen“ (необязательно): Асинхронный генератор, вызвавший

    исключение.

Примечание

Этот метод не следует перегружать в подклассах циклов обработки событий. Для пользовательской обработки исключений используйте метод set_exception_handler().

Включение режима отладки

loop.get_debug()

Получите режим отладки (bool) цикла обработки событий.

Значением по умолчанию является True, если переменной окружения PYTHONASYNCIODEBUG присвоено значение непустой строки, False в противном случае.

loop.set_debug(enabled: bool)

Установите режим отладки цикла обработки событий.

Изменено в версии 3.7: Новый Python Development Mode теперь также можно использовать для включения режима отладки.

loop.slow_callback_duration

Этот атрибут можно использовать для установки минимальной продолжительности выполнения в секундах, которая считается «медленной». Когда включен режим отладки, регистрируются «медленные» обратные вызовы.

Значение по умолчанию - 100 миллисекунд.

См.также

Значение debug mode of asyncio.

Выполняемые подпроцессы

Методы, описанные в этом подразделе, являются низкоуровневыми. В обычном асинхронном/ожидающем коде рекомендуется использовать вместо них высокоуровневые asyncio.create_subprocess_shell() и asyncio.create_subprocess_exec() удобные функции.

Примечание

В Windows цикл обработки событий по умолчанию ProactorEventLoop поддерживает подпроцессы, в то время как SelectorEventLoop этого не делает. Подробнее см. Subprocess Support on Windows.

coroutine loop.subprocess_exec(protocol_factory, *args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)

Создайте подпроцесс из одного или нескольких строковых аргументов, указанных в args.

аргументы должны быть списком строк, представленных:

В первой строке указывается исполняемый файл программы, а в остальных строках указываются аргументы. Вместе взятые, строковые аргументы из argv программы.

Это похоже на класс стандартной библиотеки subprocess.Popen, вызываемый с помощью shell=False и списка строк, передаваемого в качестве первого аргумента; однако, если Popen принимает один аргумент, который является списком строк, subprocess_exec принимает несколько строковые аргументы.

Параметр protocol_factory должен быть вызываемым, возвращающим подкласс класса asyncio.SubprocessProtocol.

Другие параметры:

  • stdin может быть любым из этих значений:

    • файлообразный объект, представляющий канал, который должен быть подключен к стандартному входному потоку подпроцесса с помощью connect_write_pipe()

    • константа subprocess.PIPE (по умолчанию), которая создаст новый канал и соединит его,

    • значение None, которое заставит подпроцесс наследовать файловый дескриптор от этого процесса

    • константа subprocess.DEVNULL, указывающая на то, что будет использоваться специальный файл os.devnull

  • стандартный вывод может быть любым из этих:

    • файлообразный объект, представляющий канал, который должен быть подключен к стандартному выходному потоку подпроцесса с помощью connect_write_pipe()

    • константа subprocess.PIPE (по умолчанию), которая создаст новый канал и соединит его,

    • значение None, которое заставит подпроцесс наследовать файловый дескриптор от этого процесса

    • константа subprocess.DEVNULL, указывающая на то, что будет использоваться специальный файл os.devnull

  • stderr может быть любым из этих значений:

    • файлообразный объект, представляющий канал, который должен быть подключен к стандартному потоку ошибок подпроцесса с помощью connect_write_pipe()

    • константа subprocess.PIPE (по умолчанию), которая создаст новый канал и соединит его,

    • значение None, которое заставит подпроцесс наследовать файловый дескриптор от этого процесса

    • константа subprocess.DEVNULL, указывающая на то, что будет использоваться специальный файл os.devnull

    • константа subprocess.STDOUT, которая соединит стандартный поток ошибок со стандартным выходным потоком процесса

  • Все остальные аргументы ключевого слова передаются в subprocess.Popen без интерпретации, за исключением bufsize, universal_newlines, shell, text, encoding и errors, которые вообще не следует указывать.

    API подпроцесса asyncio не поддерживает декодирование потоков в виде текста. bytes.decode() может использоваться для преобразования байтов, возвращаемых из потока, в текст.

Смотрите конструктор класса 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, закодированной в filesystem encoding, используя синтаксис «оболочки» платформы.

Это похоже на класс стандартной библиотеки subprocess.Popen, вызываемый с помощью shell=True.

Параметр protocol_factory должен быть вызываемым, возвращающим подкласс класса SubprocessProtocol.

Смотрите subprocess_exec() для получения более подробной информации об остальных аргументах.

Возвращает пару (transport, protocol), где transport соответствует базовому классу SubprocessTransport, а protocol является объектом, созданным с помощью protocol_factory.

Примечание

Приложение несет ответственность за то, чтобы все пробелы и специальные символы были заключены в соответствующие кавычки, чтобы избежать уязвимостей shell injection. Функция shlex.quote() может использоваться для правильного экранирования пробелов и специальных символов в строках, которые будут использоваться для создания команд оболочки.

Дескрипторы обратного вызова

class asyncio.Handle

Объект-оболочка обратного вызова, возвращаемый loop.call_soon(), loop.call_soon_threadsafe().

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 задача.

Пример:

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())

Availability: Unix, Windows.

class asyncio.ProactorEventLoop

Цикл обработки событий для Windows, использующий «Порты завершения ввода-вывода» (IOCP).

Availability: Окна.

class asyncio.AbstractEventLoop

Абстрактный базовый класс для асинхронно-совместимых циклов обработки событий.

В разделе Цикл обработки событий перечислены все методы, которые должны были быть определены в альтернативной реализации 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()

См.также

Аналогичный пример Hello World, созданный с помощью сопрограммы и функции 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()

См.также

Аналогичный пример current date, созданный с помощью сопрограммы и функции 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()

См.также

  • Аналогичный example с использованием транспортных средств, протоколов и метода loop.create_connection().

  • Другой аналогичный example, использующий высокоуровневую функцию 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())
Вернуться на верх