Spec-Zone.ru › Python 3.13

Цикл событий

Исходный код: 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 и задач
  • Открытие сетевых подключений
  • Создание сетевых серверов
  • Передача файлов
  • Переход на TLS
  • Отслеживание файловых дескрипторов
  • Работа непосредственно с объектами сокетов
  • DNS
  • Работа с каналами
  • Сигналы Unix
  • Выполнение кода в пулах потоков или процессов
  • API обработки ошибок
  • Включение режима отладки
  • Запуск подпроцессов

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

loop.run_until_complete(future)

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

Если аргументом является объект сопрограммы, его выполнение неявно планируется как asyncio.Task.

Возвращает результат Future или вызывает его исключение.

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

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

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

Этот метод очищает все очереди и завершает работу исполнителя, но не дожидается завершения исполнителя.

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

async loop.shutdown_asyncgens()

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

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

Пример:

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

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

async loop.shutdown_default_executor(timeout=None)

Планирует закрытие исполнителя по умолчанию и дожидается завершения всех потоков в ThreadPoolExecutor. После вызова этого метода использование исполнителя по умолчанию с помощью loop.run_in_executor() приведёт к возникновению RuntimeError.

Параметр timeout задаёт время (в секундах float), которое будет предоставлено исполнителю для завершения потоков. При значении по умолчанию None исполнителю предоставляется неограниченное время.

Если время ожидания timeout истечёт, будет выдано предупреждение 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 не указан, используется текущий контекст.

Примечание

Для повышения производительности обратные вызовы, запланированные с помощью loop.call_later(), могут быть выполнены раньше на величину до одного разрешения часов (см. time.get_clock_info('monotonic').resolution).

Изменено в версии 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, который можно использовать для отмены обратного вызова.

Примечание

Для повышения производительности обратные вызовы, запланированные с помощью loop.call_at(), могут быть выполнены раньше на величину до одного разрешения часов (см. time.get_clock_info('monotonic').resolution).

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

Планирует выполнение сопрограммы coro. Возвращает объект Task.

Сторонние циклы событий могут использовать собственный подкласс Task для обеспечения взаимодействия. В этом случае результат будет экземпляром подкласса Task.

Полная сигнатура функции в основном совпадает с сигнатурой конструктора (или фабрики) Task — все именованные аргументы этой функции передаются в этот интерфейс, за исключением name и context, если он равен None.

Если аргумент name указан и не равен None, он устанавливается в качестве имени задачи с помощью Task.set_name().

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

Изменено в версии 3.8: Добавлен параметр name.

Изменено в версии 3.11: Добавлен параметр context.

Изменено в версии 3.13.3: Добавлен kwargs, передающий произвольные дополнительные параметры, включая name и context.

Изменено в версии 3.13.4: Отменено изменение, при котором передавались name и context (если он равен None); при этом остальные произвольные именованные аргументы по-прежнему передаются (во избежание нарушения обратной совместимости с версией 3.13.3).

loop.set_task_factory(factory)

Устанавливает фабрику задач, которая будет использоваться методом loop.create_task().

Если factory равен None, будет установлена фабрика задач по умолчанию. В противном случае factory должен быть вызываемым объектом с сигнатурой, соответствующей (loop, coro, **kwargs), где loop — ссылка на активный цикл событий, а coro — объект сопрограммы. Вызываемый объект должен передавать все аргументы kwargs и возвращать объект, совместимый с asyncio.Task.

Изменено в версии 3.13.3: Добавлено требование передавать все аргументы kwargs в asyncio.Task.

Изменено в версии 3.13.4: Аргумент name больше не передаётся фабрикам задач. Аргумент context также не передаётся фабрикам задач, если он равен None.

loop.get_task_factory()

Возвращает фабрику задач или None, если используется фабрика по умолчанию.

Открытие сетевых подключений

async 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).

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

  1. Устанавливается соединение, и для него создаётся транспорт.
  2. Вызывается protocol_factory без аргументов; ожидается, что он вернёт экземпляр протокола.
  3. Экземпляр протокола связывается с транспортом вызовом метода connection_made().
  4. В случае успеха возвращается кортеж (transport, protocol).

Созданный транспорт представляет собой двунаправленный поток, конкретная реализация которого зависит от платформы.

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

  • ssl: если задано и не равно false, создаётся транспорт SSL/TLS (по умолчанию создаётся обычный транспорт TCP). Если ssl — объект ssl.SSLContext, для создания транспорта используется этот контекст; если ssl равно True, используется контекст по умолчанию, возвращаемый функцией ssl.create_default_context().

    См. также

    Рекомендации по безопасности SSL/TLS

  • 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-соединения) до прерывания соединения. Если задано None (значение по умолчанию), используется 60.0 секунд.
  • ssl_shutdown_timeout — время в секундах ожидания завершения отключения SSL до прерывания соединения. Если задано None (значение по умолчанию), используется 30.0 секунд.
  • 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.

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

    Примечание

    В Windows при использовании цикла событий proactor с local_addr=None во время выполнения будет возбуждено исключение OSError с errno.WSAEINVAL.

  • remote_addr, если указан, — кортеж (remote_host, remote_port), используемый для подключения сокета к удалённому адресу. Значения remote_host и remote_port определяются с помощью getaddrinfo().
  • family, proto, flags — необязательные семейство адресов, протокол и флаги, передаваемые в getaddrinfo() для определения адреса host. Если они указаны, все они должны быть целыми числами из соответствующих констант модуля socket.
  • reuse_port указывает ядру разрешить привязку этой конечной точки к тому же порту, что и у других существующих конечных точек, при условии, что при создании для всех них установлен этот флаг. Этот параметр не поддерживается в Windows и некоторых системах Unix. Если константа 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 вызовет исключение.

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

async 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.

Создание сетевых серверов

async 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, keep_alive=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, не дожидаясь окончания его естественного тайм-аута. Если параметр не указан, в Unix ему автоматически присваивается значение True.
  • reuse_port указывает ядру разрешить привязку этой конечной точки к тому же порту, что и у других существующих конечных точек, при условии, что при создании для всех них установлен этот флаг. Этот параметр не поддерживается в Windows.
  • Если для keep_alive задано значение True, соединения остаются активными благодаря периодической отправке сообщений.

Изменено в версии 3.13: Добавлен параметр keep_alive.

  • ssl_handshake_timeout — время в секундах ожидания завершения TLS-рукопожатия для TLS-сервера до прерывания соединения. Если задано None (значение по умолчанию), используется 60.0 секунд.
  • ssl_shutdown_timeout — время в секундах ожидания завершения отключения SSL до прерывания соединения. Если задано None (значение по умолчанию), используется 30.0 секунд.
  • Если для 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.

async 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, cleanup_socket=True)

Аналогичен loop.create_server(), но работает с семейством сокетов AF_UNIX.

path — имя доменного сокета Unix. Этот аргумент обязателен, если не указан аргумент sock. Поддерживаются абстрактные сокеты Unix, пути типа str, bytes и Path.

Если параметр cleanup_socket равен true, при закрытии сервера сокет Unix автоматически удаляется из файловой системы, если только после создания сервера он не был заменён.

Сведения об аргументах этого метода см. в документации метода loop.create_server().

Доступность: Unix.

Изменено в версии 3.7: Добавлены параметры ssl_handshake_timeout и start_serving. Теперь в качестве параметра path можно передавать объект Path.

Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.

Изменено в версии 3.13: Добавлен параметр cleanup_socket.

async 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-соединения до прерывания соединения. Если задано None (значение по умолчанию), используется 60.0 секунд.
  • ssl_shutdown_timeout — время в секундах ожидания завершения отключения SSL до прерывания соединения. Если задано None (значение по умолчанию), используется 30.0 секунд.

Возвращает пару (transport, protocol).

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

Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout.

Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.

Передача файлов

async loop.sendfile(transport, file, offset=0, count=None, *, fallback=True)

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

Если доступна функция os.sendfile(), метод использует её для высокопроизводительной передачи.

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

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

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

Возбуждает исключение SendfileNotAvailableError, если система не поддерживает системный вызов sendfile, а fallback равно False.

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

Обновление TLS

async 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-рукопожатия, прежде чем прервать соединение. 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 будет доступен для чтения.

Любой ранее зарегистрированный для fd обратный вызов отменяется и заменяется на callback.

loop.remove_reader(fd)

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

loop.add_writer(fd, callback, *args)

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

Любой ранее зарегистрированный для fd обратный вызов отменяется и заменяется на callback.

Используйте functools.partial(), чтобы передать именованные аргументы в callback.

loop.remove_writer(fd)

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

Некоторые ограничения этих методов описаны в разделе Поддержка платформ.

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

В целом реализации протоколов, использующие API на основе транспорта, например loop.create_connection() и loop.create_server(), быстрее реализаций, работающих непосредственно с сокетами. Однако бывают случаи, когда производительность не критична, а непосредственная работа с объектами socket удобнее.

async loop.sock_recv(sock, nbytes)

Получить из sock до nbytes байт. Асинхронная версия socket.recv().

Вернуть полученные данные в виде объекта bytes.

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

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

async loop.sock_recv_into(sock, buf)

Получить данные из sock в буфер buf. Реализован по образцу блокирующего метода socket.recv_into().

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

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

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

async loop.sock_recvfrom(sock, bufsize)

Получить из sock датаграмму размером до bufsize. Асинхронная версия socket.recvfrom().

Вернуть кортеж (полученные данные, удалённый адрес).

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

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

async loop.sock_recvfrom_into(sock, buf, nbytes=0)

Получить из sock датаграмму размером до nbytes в buf. Асинхронная версия socket.recvfrom_into().

Вернуть кортеж (количество полученных байтов, удалённый адрес).

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

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

async loop.sock_sendall(sock, data)

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

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

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

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

async loop.sock_sendto(sock, data, address)

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

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

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

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

async loop.sock_connect(sock, address)

Подключить sock к удалённому сокету по адресу address.

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

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

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

См. также

loop.create_connection() и asyncio.open_connection().

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

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

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

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

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

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

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

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

Возбуждает SendfileNotAvailableError, если система не поддерживает системный вызов sendfile, а fallback равен False.

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

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

DNS

async loop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0)

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

async loop.getnameinfo(sockaddr, flags=0)

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

Примечание

Методы getaddrinfo и getnameinfo внутри используют свои синхронные версии через исполнитель по умолчанию из пула потоков цикла. Если этот исполнитель перегружен, выполнение этих методов может задерживаться, что библиотеки более высокого уровня для работы с сетью могут отражать в виде увеличения времени ожидания. Чтобы уменьшить задержки, используйте для других задач пользователя собственный исполнитель или задайте исполнитель по умолчанию с большим количеством рабочих потоков.

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

Работа с каналами

async loop.connect_read_pipe(protocol_factory, pipe)

Зарегистрировать читающий конец pipe в цикле событий.

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

pipe — это файлоподобный объект.

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

В цикле событий SelectorEventLoop для pipe устанавливается неблокирующий режим.

async 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.

См. также

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

Сигналы 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())

Обратите внимание, что для варианта 3 необходима защита точки входа (if __name__ == '__main__') из-за особенностей 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;
  • ‘source_traceback’ (необязательный): трассировка стека источника;
  • ‘handle_traceback’ (необязательный): трассировка стека дескриптора;
  • ‘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.

async 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.

async loop.subprocess_shell(protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)

Создаёт подпроцесс из cmd, который может быть строкой str или строкой bytes, закодированной с использованием кодировки файловой системы, с применением синтаксиса «оболочки» платформы.

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

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

Подробные сведения об остальных аргументах см. в описании subprocess_exec().

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

Примечание

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

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

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

Объекты Server являются асинхронными менеджерами контекста. При использовании в операторе async with гарантируется, что после завершения оператора async with объект Server будет закрыт и перестанет принимать новые подключения:

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 объект Server является асинхронным менеджером контекста.

Изменено в версии 3.11: Этот класс стал общедоступным под именем asyncio.Server в Python 3.9.11, 3.10.3 и 3.11.

close()

Прекращает обслуживание: закрывает сокеты, ожидающие подключения, и присваивает атрибуту sockets значение None.

Сокеты, представляющие уже установленные входящие подключения клиентов, остаются открытыми.

Сервер закрывается асинхронно; используйте корутину wait_closed(), чтобы дождаться закрытия сервера (и завершения всех активных подключений).

close_clients()

Закрывает все существующие входящие подключения клиентов.

Вызывает close() для всех связанных транспортов.

При закрытии сервера следует вызвать close() перед close_clients(), чтобы избежать конфликтов при подключении новых клиентов.

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

abort_clients()

Немедленно закрывает все существующие входящие подключения клиентов, не дожидаясь завершения ожидающих операций.

Вызывает abort() для всех связанных транспортов.

При закрытии сервера следует вызвать close() перед abort_clients(), чтобы избежать конфликтов при подключении новых клиентов.

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

get_loop()

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

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

async start_serving()

Начинает принимать подключения.

Этот метод идемпотентен, поэтому его можно вызывать, даже если сервер уже принимает подключения.

Параметр start_serving, указываемый только по имени, в функциях loop.create_server() и asyncio.start_server() позволяет создать объект Server, который изначально не принимает подключения. В этом случае можно использовать Server.start_serving() или Server.serve_forever(), чтобы сервер начал принимать подключения.

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

async serve_forever()

Начинает принимать подключения и продолжает это делать, пока корутина не будет отменена. Отмена задачи serve_forever приводит к закрытию сервера.

Этот метод можно вызывать, если сервер уже принимает подключения. Для одного объекта Server может существовать только одна задача 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.

async wait_closed()

Ожидает завершения метода close() и окончания всех активных подключений.

sockets

Список объектов, подобных сокетам, asyncio.trsock.TransportSocket, на которых сервер ожидает подключения.

Изменено в версии 3.7: До Python 3.7 Server.sockets возвращал напрямую внутренний список сокетов сервера. В версии 3.7 возвращается копия этого списка.

Реализации цикла событий

В asyncio входят две различные реализации цикла событий: SelectorEventLoop и ProactorEventLoop.

По умолчанию asyncio настроен на использование EventLoop.

class asyncio.SelectorEventLoop

Подкласс AbstractEventLoop, основанный на модуле 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

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

Доступность: Windows.

См. также

Документация MSDN о портах завершения ввода-вывода.

class asyncio.EventLoop

Псевдоним наиболее эффективного доступного подкласса AbstractEventLoop для данной платформы.

В Unix это псевдоним SelectorEventLoop, а в Windows — ProactorEventLoop.

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

class asyncio.AbstractEventLoop

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

В разделе Методы цикла событий перечислены все методы, которые должны быть определены в альтернативной реализации AbstractEventLoop.

Примеры

Обратите внимание, что во всех примерах этого раздела намеренно показано использование низкоуровневых API цикла событий, таких как loop.run_forever() и loop.call_soon(). Современные приложения asyncio редко требуется писать таким образом; рассмотрите возможность использования высокоуровневых функций, например asyncio.run().

Hello World с 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()

См. также

Похожий пример текущей даты, созданный с помощью корутины и функции 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–2025 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.13/library/asyncio-eventloop.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API