Цикл событий
Исходный код: 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.14: Вызывает
RuntimeError, если текущий цикл событий отсутствует.Примечание
Система политик
asyncioобъявлена устаревшей и будет удалена в Python 3.16; после этого функция будет возвращать текущий работающий цикл событий, если он есть, в противном случае — цикл, заданный с помощьюset_event_loop().
-
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, eager_start=None, **kwargs) -
Планирует выполнение сопрограммы coro. Возвращает объект
Task.Сторонние циклы событий могут использовать собственный подкласс
Taskдля обеспечения совместимости. В этом случае тип результата является подклассомTask.Полная сигнатура функции во многом совпадает с сигнатурой конструктора (или фабрики)
Task— все аргументы-ключевые слова этой функции передаются этому интерфейсу.Если аргумент name указан и не равен
None, он задается как имя задачи с помощьюTask.set_name().Необязательный аргумент context, указываемый только по имени, позволяет задать пользовательский
contextvars.Contextдля выполнения coro. Если context не задан, создается копия текущего контекста.Необязательный аргумент eager_start, указываемый только по имени, позволяет указать, должна ли задача выполняться немедленно при вызове create_task или быть запланирована на более позднее время. Если eager_start не передан, используется режим, заданный с помощью
loop.set_task_factory().Изменено в версии 3.8: Добавлен параметр name.
Изменено в версии 3.11: Добавлен параметр context.
Изменено в версии 3.13.3: Добавлен
kwargs, который передает произвольные дополнительные параметры, включаяnameиcontext.Изменено в версии 3.13.4: Отменено изменение, передававшее name и context (если он равен None), при этом остальные произвольные аргументы-ключевые слова по-прежнему передаются (чтобы не нарушать обратную совместимость с версией 3.13.3).
Изменено в версии 3.14: Теперь передаются все kwargs. Параметр eager_start работает с фабриками задач с немедленным запуском.
-
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.Изменено в версии 3.14: Теперь name и context снова всегда передаются фабрикам задач.
-
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).Последовательность выполнения базовой операции выглядит следующим образом:
- Устанавливается соединение и для него создаётся транспорт.
- Вызывается protocol_factory без аргументов; предполагается, что он вернёт экземпляр протокола.
- Экземпляр протокола связывается с транспортом вызовом его метода
connection_made(). - В случае успеха возвращается кортеж
(transport, protocol).
Созданный транспорт представляет собой двунаправленный поток, реализация которого зависит от платформы.
Прочие аргументы:
-
ssl: если аргумент указан и не является ложным значением, создаётся транспорт SSL/TLS (по умолчанию создаётся обычный транспорт TCP). Если ssl — объект
ssl.SSLContext, этот контекст используется для создания транспорта; если ssl —True, используется контекст по умолчанию, возвращаемый функциейssl.create_default_context().См. также
-
server_hostname задаёт или переопределяет имя хоста, с которым будет сравниваться сертификат целевого сервера. Этот аргумент следует передавать, только если ssl не равен
None. По умолчанию используется значение аргумента host. Если host пуст, значение по умолчанию отсутствует, и необходимо передать значение для server_hostname. Если server_hostname — пустая строка, проверка имени хоста отключается (что представляет серьёзную угрозу безопасности, поскольку допускает потенциальные атаки типа «человек посередине»). -
family, proto, flags — необязательные семейство адресов, протокол и флаги, передаваемые в getaddrinfo() для разрешения имени host. Если они указаны, все они должны быть целыми числами из соответствующих констант модуля
socket. -
happy_eyeballs_delay, если указан, включает алгоритм Happy Eyeballs для этого соединения. Он должен быть числом с плавающей точкой, задающим время в секундах ожидания завершения попытки подключения, прежде чем параллельно начать следующую попытку. Это «задержка между попытками подключения», определённая в RFC 8305. Рекомендуемое RFC разумное значение по умолчанию —
0.25(250 миллисекунд). -
interleave управляет изменением порядка адресов, когда имя хоста разрешается в несколько IP-адресов. Если значение равно
0или не задано, порядок не меняется, а адреса проверяются в порядке, возвращаемом функциейgetaddrinfo(). Если указано положительное целое число, адреса чередуются по семействам адресов, а это число интерпретируется как «количество адресов первого семейства», определённое в RFC 8305. По умолчанию используется0, если happy_eyeballs_delay не указан, и1, если указан. -
sock, если указан, должен быть существующим, уже подключённым объектом
socket.socket, который будет использоваться транспортом. Если указан sock, нельзя указывать host, port, family, proto, flags, happy_eyeballs_delay, interleave и local_addr.Примечание
Аргумент sock передаёт созданному транспорту право владения сокетом. Чтобы закрыть сокет, вызовите метод транспорта
close(). -
local_addr, если указан, — это кортеж
(local_host, local_port), используемый для локальной привязки сокета. Значения local_host и local_port определяются с помощьюgetaddrinfo(), аналогично host и port. -
ssl_handshake_timeout — время в секундах ожидания завершения рукопожатия TLS (для TLS-соединения) до прерывания соединения.
60.0секунд, если значение равноNone(по умолчанию). -
ssl_shutdown_timeout — время в секундах ожидания завершения отключения SSL до прерывания соединения.
30.0секунд, если значение равноNone(по умолчанию). -
all_errors определяет, какие исключения вызываются, если не удаётся создать соединение. По умолчанию вызывается только одно исключение
Exception: первое, если исключение только одно или все ошибки имеют одинаковое сообщение, либо одно исключениеOSErrorс объединёнными сообщениями об ошибках. Еслиall_errorsравноTrue, будет вызвано исключениеExceptionGroup, содержащее все исключения (даже если оно только одно).
Изменено в версии 3.5: Добавлена поддержка SSL/TLS в
ProactorEventLoop.Изменено в версии 3.6: Параметр сокета socket.TCP_NODELAY по умолчанию устанавливается для всех TCP-соединений.
Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout.
Изменено в версии 3.8: Добавлены параметры happy_eyeballs_delay и interleave.
Алгоритм Happy Eyeballs: успешная работа с узлами с двойным стеком. Если путь и протокол IPv4 на сервере работают, а путь и протокол IPv6 — нет, клиентское приложение с двойным стеком сталкивается со значительной задержкой подключения по сравнению с клиентом, использующим только IPv4. Это нежелательно, поскольку ухудшает взаимодействие пользователя с клиентом с двойным стеком. В этом документе указаны требования к алгоритмам, уменьшающим такую заметную пользователю задержку, а также описан один из алгоритмов.
Дополнительная информация: https://datatracker.ietf.org/doc/html/rfc6555
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
Изменено в версии 3.12: Добавлен параметр all_errors.
См. также
Функция
open_connection()— это альтернативный API более высокого уровня. Она возвращает пару (StreamReader,StreamWriter), которую можно использовать непосредственно в коде async/await.
-
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 сообщает ядру, что этой конечной точке разрешено отправлять сообщения на широковещательный адрес.
-
Чтобы использовать существующий, уже подключённый объект
socket.socketв качестве транспорта, можно указать sock. Если он указан, аргументы 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). -
Для включения TLS на принятых соединениях параметру ssl можно присвоить экземпляр
SSLContext. -
reuse_address сообщает ядру о необходимости повторно использовать локальный сокет в состоянии
TIME_WAIT, не дожидаясь окончания естественного тайм-аута. Если параметр не указан, в Unix ему автоматически присваивается значениеTrue. - reuse_port сообщает ядру, что этой конечной точке разрешено использовать тот же порт, что и другим существующим конечным точкам, если при их создании для всех был установлен этот флаг. Этот параметр не поддерживается в Windows.
-
Если установить для keep_alive значение
True, соединения будут поддерживаться активными за счёт периодической отправки сообщений.
Изменено в версии 3.13: Добавлен параметр keep_alive.
-
ssl_handshake_timeout — время в секундах ожидания завершения рукопожатия TLS (для TLS-сервера) до прерывания соединения.
60.0секунд, если значение равноNone(по умолчанию). -
ssl_shutdown_timeout — время в секундах ожидания завершения отключения SSL до прерывания соединения.
30.0секунд, если значение равноNone(по умолчанию). -
Если для start_serving задано значение
True(по умолчанию), созданный сервер сразу начинает принимать соединения. Если задано значениеFalse, пользователь должен выполнить await для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 на принятых соединениях параметру ssl можно присвоить объект
SSLContext. -
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.
Передача файлов
-
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 и вставляет его между transport и protocol. Кодировщик/декодировщик реализует как протокол со стороны transport, так и транспорт со стороны protocol.
Возвращает созданный экземпляр с двумя интерфейсами. После await protocol должен прекратить использовать исходный transport и взаимодействовать только с возвращенным объектом, поскольку кодировщик кэширует данные со стороны protocol и время от времени обменивается с transport дополнительными пакетами сеанса TLS.
В некоторых ситуациях (например, если переданный транспорт уже закрывается) может быть возвращено
None.Параметры:
-
экземпляры transport и protocol, возвращаемые такими методами, как
create_server()иcreate_connection(). -
sslcontext: настроенный экземпляр
SSLContext. -
server_side: передайте
Trueпри переходе на TLS серверного соединения (например, созданного с помощью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.
-
экземпляры transport и protocol, возвращаемые такими методами, как
Отслеживание файловых дескрипторов
-
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 с указанными аргументами args, как только 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 должен быть неблокирующим сокетом.
В
SelectorEventLoopразрешать address не требуется: для сокетовAF_INETиAF_INET6sock_connectсначала проверяет, разрешен ли уже address, вызываяsocket.inet_pton(), и, если нет, используетloop.getaddrinfo()для его разрешения.ProactorEventLoop, цикл событий по умолчанию в Windows, не разрешает address. Хост должен уже быть числовым IP-адресом; при передаче имени хоста возбуждаетсяOSError. Сначала разрешите адрес с помощьюloop.getaddrinfo()либо используйтеloop.create_connection(), который разрешает адрес на всех платформах.Изменено в версии 3.5.2: В
SelectorEventLoopaddressбольше не требуется разрешать.См. также
-
async loop.sock_accept(sock) -
Принимает соединение. Реализован по образцу блокирующего метода
socket.accept().Сокет должен быть привязан к адресу и ожидать соединений. Возвращаемое значение — пара
(conn, address), где conn — новый объект сокета, пригодный для отправки и получения данных по соединению, а address — адрес, привязанный к сокету на другом конце соединения.sock должен быть неблокирующим сокетом.
Изменено в версии 3.7: Хотя этот метод всегда документировался как метод-корутина, до Python 3.7 он возвращал
Future. Начиная с Python 3.7 это методasync def.См. также
-
async loop.sock_sendfile(sock, file, offset=0, count=None, *, fallback=True) -
Отправляет файл, по возможности используя высокопроизводительный
os.sendfile. Возвращает общее количество отправленных байт.Асинхронная версия
socket.sendfile().sock должен быть неблокирующим сокетом
socket.SOCK_STREAMsocket.file должен быть обычным файловым объектом, открытым в двоичном режиме.
offset указывает, откуда начинать чтение файла. Если он указан, count задает общее количество передаваемых байт, вместо отправки файла до достижения EOF. Позиция в файле обновляется всегда, даже если этот метод возбуждает ошибку; для получения фактического количества отправленных байт можно использовать
file.tell().Если fallback имеет значение
True, asyncio вручную читает и отправляет файл, когда платформа не поддерживает системный вызов sendfile (например, в Windows или при использовании SSL-сокета в Unix).Возбуждает
SendfileNotAvailableError, если система не поддерживает системный вызов sendfile, а fallback имеет значениеFalse.sock должен быть неблокирующим сокетом.
Добавлено в версии 3.7.
DNS
-
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 — это объект, подобный файлу. Список объектов, которые можно использовать в качестве pipe, см. в разделе Поддерживаемые объекты каналов.
Возвращает пару
(transport, protocol), где transport поддерживает интерфейсReadTransport, а protocol — объект, созданный с помощью protocol_factory.В цикле событий
SelectorEventLoopдля pipe устанавливается неблокирующий режим.
-
async loop.connect_write_pipe(protocol_factory, pipe) -
Регистрирует конец pipe, предназначенный для записи, в цикле событий.
protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола asyncio.
pipe — это объект, подобный файлу. Список объектов, которые можно использовать в качестве pipe, см. в разделе Поддерживаемые объекты каналов.
Возвращает пару
(transport, protocol), где transport поддерживает интерфейсWriteTransport, а protocol — объект, созданный с помощью protocol_factory.В цикле событий
SelectorEventLoopдля pipe устанавливается неблокирующий режим.
Поддерживаемые объекты каналов
Эти методы работают только с объектами, готовность которых операционная система может опрашивать или с которыми она может выполнять перекрывающийся ввод-вывод. Обычные файлы на диске не поддерживаются ни на одной платформе. В asyncio нет асинхронного файлового ввода-вывода; используйте loop.run_in_executor() для чтения и записи обычных файлов без блокировки цикла событий.
В Unix при использовании SelectorEventLoop pipe должен оборачивать один из следующих объектов:
- канал, например один из концов пары, созданной с помощью
os.pipe(), или FIFO, созданный с помощьюos.mkfifo(); - сокет;
- символьное устройство, например терминал.
В Windows, где эти методы реализованы только в ProactorEventLoop, pipe должен оборачивать дескриптор, открытый для перекрывающегося ввода-вывода (то есть созданный с флагом FILE_FLAG_OVERLAPPED), поскольку дескриптор необходимо связать с портом завершения ввода-вывода. Дескрипторы, не открытые для перекрывающегося ввода-вывода, отклоняются. В частности, стандартные потоки (sys.stdin, sys.stdout и sys.stderr), дескрипторы консоли и каналы, созданные с помощью os.pipe(), не открыты для перекрывающегося ввода-вывода и поэтому не могут использоваться с этими методами.
Примечание
SelectorEventLoop не поддерживает перечисленные выше методы в Windows. В Windows вместо него используйте ProactorEventLoop.
См. также
Сигналы Unix
-
loop.add_signal_handler(signum, callback, *args) -
Назначает callback обработчиком сигнала signum, передавая args в качестве позиционных аргументов.
Обратный вызов будет вызван циклом 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 в указанном исполнителе, передав args в качестве позиционных аргументов.
Аргумент 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) # 4. Run in a custom interpreter pool: with concurrent.futures.InterpreterPoolExecutor() as pool: result = await loop.run_in_executor( pool, cpu_bound) print('custom interpreter 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, в том числеInterpreterPoolExecutor.Изменено в версии 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’ (необязательно): экземпляр Protocol;
- ‘transport’ (необязательно): экземпляр 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 миллисекунд.
См. также
Запуск подпроцессов
Методы, описанные в этом подразделе, относятся к низкоуровневому API. В обычном коде 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()и завершения всех активных подключений.Изменено в версии 3.12: Теперь
wait_closed()ожидает закрытия сервера и завершения всех активных подключений. Ранее метод возвращал управление немедленно, если сервер уже был закрыт, даже при наличии активных подключений.
-
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 async def main(): ... loop_factory = lambda: asyncio.SelectorEventLoop(selectors.SelectSelector()) asyncio.run(main(), loop_factory=loop_factory)
Доступность: Unix, Windows.
-
class asyncio.ProactorEventLoop -
Подкласс
AbstractEventLoopдля Windows, использующий «порты завершения ввода-вывода» (IOCP).Доступность: Windows.
-
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().
Привет, мир, с помощью call_soon()
Пример использования метода loop.call_soon() для планирования обратного вызова. Обратный вызов выводит "Hello World", а затем останавливает цикл событий:
import asyncio
def hello_world(loop):
"""A callback to print 'Hello World' and stop the event loop"""
print('Hello World')
loop.stop()
loop = asyncio.new_event_loop()
# Schedule a call to hello_world()
loop.call_soon(hello_world, loop)
# Blocking call interrupted by loop.stop()
try:
loop.run_forever()
finally:
loop.close()
См. также
Похожий пример «Привет, мир», созданный с помощью сопрограммы и функции run().
Отображение текущей даты с помощью call_later()
Пример обратного вызова, который каждую секунду отображает текущую дату. Обратный вызов использует метод loop.call_later(), чтобы запланировать свой повторный вызов через 5 секунд, а затем останавливает цикл событий:
import asyncio
import datetime as dt
def display_date(end_time, loop):
print(dt.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
(Этот пример signal работает только в 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 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.14/library/asyncio-eventloop.html