Цикл событий
Исходный код: 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()вместо ручного создания и закрытия цикла событий с помощью этих низкоуровневых функций.Примечание
В версиях Python 3.10.0–3.10.8 и 3.11.0 эта функция (и другие функции, использующие её неявно) выдавала предупреждение
DeprecationWarning, если работающего цикла событий не было, даже когда текущий цикл был установлен в политике. В версиях Python 3.10.9, 3.11.1 и 3.12 они выдают предупреждениеDeprecationWarning, если работающего цикла событий нет и текущий цикл не установлен. В одном из будущих выпусков Python это станет ошибкой.
-
asyncio.set_event_loop(loop) -
Устанавливает loop в качестве текущего цикла событий для текущего потока ОС.
-
asyncio.new_event_loop() -
Создаёт и возвращает новый объект цикла событий.
Обратите внимание, что поведение функций 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() -
Закрывает цикл событий.
При вызове этой функции цикл не должен работать. Все ожидающие обратные вызовы будут отброшены.
Этот метод очищает все очереди и завершает работу исполнителя, но не ожидает его завершения.
Этот метод идемпотентен и необратим. После закрытия цикла событий вызывать другие методы нельзя.
-
coroutine loop.shutdown_asyncgens() -
Планирует закрытие всех открытых на данный момент объектов асинхронного генератора с помощью вызова
aclose(). После вызова этого метода цикл событий выдаст предупреждение, если будет начат перебор нового асинхронного генератора. Этот метод следует использовать для надёжного завершения всех запланированных асинхронных генераторов.Обратите внимание: вызывать эту функцию не требуется, если используется
asyncio.run().Пример:
try: loop.run_forever() finally: loop.run_until_complete(loop.shutdown_asyncgens()) loop.close()Добавлено в версии 3.6.
-
coroutine loop.shutdown_default_executor() -
Планирует закрытие исполнителя по умолчанию и ожидает завершения всех потоков в
ThreadPoolExecutor. После вызова этого метода использование исполнителя по умолчанию с помощьюloop.run_in_executor()приведёт к возникновениюRuntimeError.Примечание
Не вызывайте этот метод при использовании
asyncio.run(), поскольку последняя автоматически завершает работу исполнителя по умолчанию.Добавлено в версии 3.9.
Планирование обратных вызовов
-
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))
Использовать объекты partial обычно удобнее, чем лямбда-функции, поскольку asyncio может лучше отображать объекты partial в сообщениях отладки и об ошибках.
Планирование отложенных обратных вызовов
Цикл событий предоставляет механизмы для планирования вызова функций обратного вызова в будущем. Для отслеживания времени цикл событий использует монотонные часы.
-
loop.call_later(delay, callback, *args, context=None) -
Планирует вызов callback через заданное число секунд delay (целое число или число с плавающей точкой).
Возвращается экземпляр
asyncio.TimerHandle, который можно использовать для отмены обратного вызова.callback будет вызван ровно один раз. Если два обратных вызова запланированы на одно и то же время, порядок их вызова не определён.
Необязательные позиционные аргументы args будут переданы обратному вызову при его вызове. Чтобы вызвать обратный вызов с аргументами по ключевым словам, используйте
functools.partial().Необязательный параметр context, который можно задавать только по ключевому слову, позволяет указать пользовательский
contextvars.Context, в котором будет выполняться callback. Если context не указан, используется текущий контекст.Изменено в версии 3.7: Добавлен параметр context, который можно задавать только по ключевому слову. Подробнее см. в PEP 567.
Изменено в версии 3.8: В Python 3.7 и более ранних версиях при использовании реализации цикла событий по умолчанию значение delay не могло превышать одни сутки. Это ограничение устранено в Python 3.8.
-
loop.call_at(when, callback, *args, context=None) -
Планирует вызов callback в указанный абсолютный момент времени when (целое число или число с плавающей точкой), используя ту же систему отсчёта времени, что и
loop.time().Этот метод ведёт себя так же, как
call_later().Возвращается экземпляр
asyncio.TimerHandle, который можно использовать для отмены обратного вызова.Изменено в версии 3.7: Добавлен параметр context, который можно задавать только по ключевому слову. Подробнее см. в PEP 567.
Изменено в версии 3.8: В Python 3.7 и более ранних версиях при использовании реализации цикла событий по умолчанию разница между when и текущим временем не могла превышать одни сутки. Это ограничение устранено в Python 3.8.
-
loop.time() -
Возвращает текущее время в виде значения типа
float, согласно внутренним монотонным часам цикла событий.
Примечание
Изменено в версии 3.8: В Python 3.7 и более ранних версиях значения тайм-аутов (относительное delay или абсолютное when) не должны были превышать одни сутки. Это ограничение устранено в Python 3.8.
См. также
Функцию asyncio.sleep().
Создание объектов Future и задач
-
loop.create_future() -
Создаёт объект
asyncio.Future, связанный с циклом событий.Это предпочтительный способ создания объектов Future в asyncio. Благодаря этому сторонние циклы событий могут предоставлять альтернативные реализации объекта Future (с более высокой производительностью или возможностями инструментирования).
Добавлено в версии 3.5.2.
-
loop.create_task(coro, *, name=None, context=None) -
Планирует выполнение сопрограммы coro. Возвращает объект
Task.Для обеспечения совместимости сторонние циклы событий могут использовать собственный подкласс
Task. В этом случае возвращаемый тип является подклассомTask.Если аргумент name указан и не равен
None, он устанавливается в качестве имени задачи с помощьюTask.set_name().Необязательный параметр context, который можно задавать только по ключевому слову, позволяет указать пользовательский
contextvars.Context, в котором будет выполняться coro. Если context не указан, создаётся копия текущего контекста.Изменено в версии 3.8: Добавлен параметр name.
Изменено в версии 3.11: Добавлен параметр context.
-
loop.set_task_factory(factory) -
Задаёт фабрику задач, которая будет использоваться методом
loop.create_task().Если factory равен
None, будет установлена фабрика задач по умолчанию. В противном случае factory должен быть вызываемым объектом с сигнатурой, соответствующей(loop, coro, context=None), где loop — ссылка на активный цикл событий, а coro — объект сопрограммы. Вызываемый объект должен возвращать объект, совместимый сasyncio.Future.
-
loop.get_task_factory() -
Возвращает фабрику задач или
None, если используется фабрика по умолчанию.
Открытие сетевых подключений
-
coroutine loop.create_connection(protocol_factory, host=None, port=None, *, ssl=None, family=0, proto=0, flags=0, sock=None, local_addr=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, happy_eyeballs_delay=None, interleave=None) -
Открыть потоковое транспортное подключение к адресу, заданному параметрами host и port.
Семейство сокета может быть
AF_INETилиAF_INET6в зависимости от host (или аргумента family, если он указан).Тип сокета будет
SOCK_STREAM.protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола asyncio.
Этот метод попытается установить подключение в фоновом режиме. В случае успеха он вернёт пару
(transport, protocol).Последовательность базовой операции во времени выглядит следующим образом:
- Устанавливается подключение и создаётся транспорт.
- Вызывается protocol_factory без аргументов; ожидается, что он вернёт экземпляр протокола.
- Экземпляр протокола связывается с транспортом вызовом метода
connection_made(). - В случае успеха возвращается кортеж
(transport, protocol).
Созданный транспорт представляет собой двунаправленный поток, реализация которого зависит от платформы.
Другие аргументы:
-
ssl: если задан и не равен false, создаётся транспорт SSL/TLS (по умолчанию создаётся обычный транспорт TCP). Если ssl — объект
ssl.SSLContext, этот контекст используется для создания транспорта; если ssl равенTrue, используется контекст по умолчанию, возвращаемый функциейssl.create_default_context().См. также
-
server_hostname задаёт или переопределяет имя узла, с которым будет сверяться сертификат целевого сервера. Указывать его следует только в том случае, если ssl не равен
None. По умолчанию используется значение аргумента host. Если host пуст, значение по умолчанию отсутствует, и необходимо передать значение для server_hostname. Если server_hostname — пустая строка, проверка имени узла отключается (это серьёзный риск безопасности, поскольку возможны атаки типа «человек посередине»). -
family, proto, flags — необязательные семейство адресов, протокол и флаги, передаваемые в getaddrinfo() для разрешения имени host. Если они указаны, все они должны быть целыми числами, соответствующими константам модуля
socket. -
happy_eyeballs_delay, если задан, включает алгоритм Happy Eyeballs для этого подключения. Он должен быть числом с плавающей точкой, обозначающим время в секундах ожидания завершения попытки подключения перед запуском следующей попытки параллельно. Это «задержка между попытками подключения» (Connection Attempt Delay), определённая в RFC 8305. Рекомендуемое RFC разумное значение по умолчанию —
0.25(250 миллисекунд). -
interleave управляет изменением порядка адресов, когда имя узла разрешается в несколько IP-адресов. Если задано
0или значение не указано, порядок не меняется и адреса проверяются в том порядке, в котором их возвращаетgetaddrinfo(). Если указано положительное целое число, адреса чередуются по семействам адресов, а это целое число трактуется как «количество адресов первого семейства» (First Address Family Count), определённое в 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секунд.
Изменено в версии 3.5: Добавлена поддержка SSL/TLS в
ProactorEventLoop.Изменено в версии 3.6: Для всех TCP-подключений по умолчанию устанавливается параметр сокета socket.TCP_NODELAY.
Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout.
Изменено в версии 3.8: Добавлены параметры happy_eyeballs_delay и interleave.
Алгоритм Happy Eyeballs: успешная работа с узлами с двумя стеками протоколов. Если путь и протокол IPv4 на сервере работают, а путь и протокол IPv6 — нет, приложение-клиент с двумя стеками протоколов испытывает значительную задержку подключения по сравнению с клиентом, использующим только IPv4. Это нежелательно, поскольку ухудшает взаимодействие пользователя с приложением-клиентом с двумя стеками протоколов. В этом документе задаются требования к алгоритмам, уменьшающим такую заметную для пользователя задержку, и приводится один из алгоритмов.
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
См. также
Функция
open_connection()— это альтернативный API высокого уровня. Она возвращает пару (StreamReader,StreamWriter), которую можно напрямую использовать в коде async/await.
-
coroutine loop.create_datagram_endpoint(protocol_factory, local_addr=None, remote_addr=None, *, family=0, proto=0, flags=0, reuse_port=None, allow_broadcast=None, sock=None) -
Создать датаграммное подключение.
Семейство сокета может быть
AF_INET,AF_INET6илиAF_UNIXв зависимости от host (или аргумента family, если он указан).Тип сокета будет
SOCK_DGRAM.protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола.
В случае успеха возвращается кортеж из
(transport, protocol).Другие аргументы:
-
local_addr, если задан, представляет собой кортеж
(local_host, local_port), используемый для локальной привязки сокета. Значения local_host и local_port определяются с помощьюgetaddrinfo(). -
remote_addr, если задан, представляет собой кортеж
(remote_host, remote_port), используемый для подключения сокета к удалённому адресу. Значения remote_host и remote_port определяются с помощьюgetaddrinfo(). -
family, proto, flags — необязательные семейство адресов, протокол и флаги, передаваемые в
getaddrinfo()для разрешения имени host. Если они указаны, все они должны быть целыми числами, соответствующими константам модуляsocket. - reuse_port указывает ядру разрешить привязку этой конечной точки к тому же порту, что и у других существующих конечных точек, если при их создании для всех был установлен этот флаг. Этот параметр не поддерживается в Windows и некоторых системах 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, полностью удалён.
-
local_addr, если задан, представляет собой кортеж
-
coroutine loop.create_unix_connection(protocol_factory, path=None, *, ssl=None, sock=None, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None) -
Создать подключение Unix.
Семейством сокета будет
AF_UNIX; типом сокета будетSOCK_STREAM.В случае успеха возвращается кортеж из
(transport, protocol).path — имя доменного сокета Unix; этот аргумент обязателен, если не указан параметр sock. Поддерживаются абстрактные сокеты Unix, пути типа
str,bytesиPath.Сведения об аргументах этого метода см. в документации метода
loop.create_connection().Доступность: Unix.
Изменено в версии 3.7: Добавлен параметр ssl_handshake_timeout. Теперь параметр path может быть объектом, поддерживающим протокол путей.
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
Создание сетевых серверов
-
coroutine loop.create_server(protocol_factory, host=None, port=None, *, family=socket.AF_UNSPEC, flags=socket.AI_PASSIVE, sock=None, backlog=100, ssl=None, reuse_address=None, reuse_port=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True) -
Создать TCP-сервер (тип сокета
SOCK_STREAM), прослушивающий порт port по адресу host.Возвращает объект
Server.Аргументы:
- protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола.
-
Параметру host можно присвоить значения нескольких типов, определяющие, где будет прослушиваться сервер:
- Если host — строка, TCP-сервер привязывается к одному сетевому интерфейсу, заданному параметром host.
- Если host — последовательность строк, TCP-сервер привязывается ко всем сетевым интерфейсам, указанным в последовательности.
- Если host — пустая строка или
None, предполагаются все интерфейсы, и возвращается список из нескольких сокетов (скорее всего, один для IPv4, а другой для IPv6).
- Параметр port задаёт порт, который должен прослушивать сервер. Если указано
0илиNone(значение по умолчанию), будет выбран случайный неиспользуемый порт (обратите внимание: если host разрешается в несколько сетевых интерфейсов, для каждого интерфейса будет выбран отдельный случайный порт). -
Для принудительного использования IPv4 или IPv6 сокетом параметру family можно присвоить
socket.AF_INETилиAF_INET6. Если параметр не задан, значение 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.
-
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. Для всех TCP-подключений по умолчанию устанавливается параметр сокета socket.TCP_NODELAY.
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
См. также
Функция
start_server()— это альтернативный API более высокого уровня, возвращающий пару изStreamReaderиStreamWriter, которые можно использовать в коде async/await.
-
coroutine loop.create_unix_server(protocol_factory, path=None, *, sock=None, backlog=100, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True) -
Аналогичен
loop.create_server(), но работает с семейством сокетовAF_UNIX.path — имя доменного сокета Unix; этот аргумент обязателен, если не указан аргумент sock. Поддерживаются абстрактные сокеты Unix, пути типа
str,bytesиPath.Сведения об аргументах этого метода см. в документации метода
loop.create_server().Доступность: Unix.
Изменено в версии 3.7: Добавлены параметры ssl_handshake_timeout и start_serving. Теперь параметр path может быть объектом
Path.Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
-
coroutine loop.connect_accepted_socket(protocol_factory, sock, *, ssl=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None) -
Обернуть уже принятое подключение в пару транспорт/протокол.
Этот метод могут использовать серверы, принимающие подключения вне asyncio, но обрабатывающие их с помощью asyncio.
Параметры:
- protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола.
-
sock — существующий объект сокета, возвращённый методом
socket.accept.Примечание
Аргумент sock передаёт созданному транспорту владение сокетом. Чтобы закрыть сокет, вызовите метод транспорта
close(). -
Параметру ssl можно присвоить экземпляр
SSLContext, чтобы включить SSL для принятых подключений. -
ssl_handshake_timeout — время в секундах ожидания завершения SSL-рукопожатия (для SSL-подключения) до прерывания подключения. Если задано
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.
Передача файлов
-
coroutine loop.sendfile(transport, file, offset=0, count=None, *, fallback=True) -
Отправить file через transport. Возвращает общее количество отправленных байтов.
Если доступен, метод использует высокопроизводительный
os.sendfile().file должен быть обычным файловым объектом, открытым в двоичном режиме.
offset указывает, с какого места начинать чтение файла. Если он задан, count задаёт общее количество байтов для передачи, а не отправку файла до достижения EOF. Позиция в файле обновляется всегда, даже если этот метод вызывает ошибку; чтобы получить фактическое количество отправленных байтов, можно использовать
file.tell().Если задано значение
Trueдля fallback, asyncio будет вручную читать и отправлять файл, когда платформа не поддерживает системный вызов sendfile (например, в Windows или при использовании SSL-сокета в Unix).Вызывает исключение
SendfileNotAvailableError, если система не поддерживает системный вызов sendfile, а fallback равенFalse.Добавлено в версии 3.7.
Переход на TLS
-
coroutine loop.start_tls(transport, protocol, sslcontext, *, server_side=False, server_hostname=None, ssl_handshake_timeout=None, ssl_shutdown_timeout=None) -
Перевести существующее подключение на основе транспорта на TLS.
Создать экземпляр кодировщика/декодировщика TLS и вставить его между transport и protocol. Кодировщик/декодировщик реализует протокол со стороны transport и транспорт со стороны protocol.
Возвращает созданный экземпляр с двумя интерфейсами. После await протокол должен перестать использовать исходный transport и взаимодействовать только с возвращённым объектом, поскольку кодировщик кэширует данные со стороны protocol и время от времени обменивается дополнительными пакетами сеанса TLS с transport.
В некоторых ситуациях (например, если переданный транспорт уже закрывается) метод может вернуть
None.Параметры:
-
Экземпляры transport и protocol, возвращаемые такими методами, как
create_server()иcreate_connection(). -
sslcontext: настроенный экземпляр
SSLContext. -
Для обновления подключения на стороне сервера (например, созданного методом
create_server()) передайте для server_side значениеTrue. - server_hostname: задаёт или переопределяет имя узла, с которым будет сверяться сертификат целевого сервера.
-
ssl_handshake_timeout — время в секундах ожидания завершения TLS-рукопожатия (для TLS-подключения) до прерывания подключения. Если задано
None(по умолчанию), используется60.0секунд. -
ssl_shutdown_timeout — время в секундах ожидания завершения отключения SSL до прерывания подключения. Если задано
None(по умолчанию), используется30.0секунд.
Добавлено в версии 3.7.
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
-
Экземпляры transport и protocol, возвращаемые такими методами, как
Наблюдение за файловыми дескрипторами
-
loop.add_reader(fd, callback, *args) -
Начать отслеживать возможность чтения файлового дескриптора fd и вызвать callback с указанными аргументами, когда fd станет доступен для чтения.
-
loop.remove_reader(fd) -
Прекратить отслеживать возможность чтения файлового дескриптора fd. Возвращает
True, если ранее fd отслеживался для чтения.
-
loop.add_writer(fd, callback, *args) -
Начать отслеживать возможность записи в файловый дескриптор fd и вызвать callback с указанными аргументами, когда fd станет доступен для записи.
Используйте
functools.partial()для передачи именованных аргументов в callback.
-
loop.remove_writer(fd) -
Прекратить отслеживать возможность записи в файловый дескриптор fd. Возвращает
True, если ранее fd отслеживался для записи.
Сведения об ограничениях этих методов см. также в разделе Поддержка платформ.
Непосредственная работа с объектами сокетов
Как правило, реализации протоколов, использующие API на основе транспортов, например loop.create_connection() и loop.create_server(), работают быстрее, чем реализации, напрямую работающие с сокетами. Однако в некоторых случаях производительность не критична, и непосредственная работа с объектами socket удобнее.
-
coroutine loop.sock_recv(sock, nbytes) -
Получить из sock не более nbytes байт. Асинхронная версия
socket.recv().Возвращает полученные данные в виде объекта bytes.
sock должен быть неблокирующим сокетом.
Изменено в версии 3.7: Хотя этот метод всегда документировался как корутинный, в выпусках до Python 3.7 он возвращал
Future. Начиная с Python 3.7 это методasync def.
-
coroutine loop.sock_recv_into(sock, buf) -
Получить данные из sock в буфер buf. Реализован по образцу блокирующего метода
socket.recv_into().Возвращает количество байт, записанных в буфер.
sock должен быть неблокирующим сокетом.
Добавлено в версии 3.7.
-
coroutine loop.sock_recvfrom(sock, bufsize) -
Получить из sock дейтаграмму размером не более bufsize. Асинхронная версия
socket.recvfrom().Возвращает кортеж (полученные данные, удалённый адрес).
sock должен быть неблокирующим сокетом.
Добавлено в версии 3.11.
-
coroutine loop.sock_recvfrom_into(sock, buf, nbytes=0) -
Получить из sock дейтаграмму размером не более nbytes в buf. Асинхронная версия
socket.recvfrom_into().Возвращает кортеж (количество полученных байт, удалённый адрес).
sock должен быть неблокирующим сокетом.
Добавлено в версии 3.11.
-
coroutine loop.sock_sendall(sock, data) -
Отправить data в сокет sock. Асинхронная версия
socket.sendall().Этот метод продолжает отправлять данные в сокет, пока все данные из data не будут отправлены или не произойдёт ошибка. При успешном выполнении возвращается
None. В случае ошибки вызывается исключение. Кроме того, определить, сколько данных, если таковые были, успешно обработала принимающая сторона соединения, невозможно.sock должен быть неблокирующим сокетом.
Изменено в версии 3.7: Хотя этот метод всегда документировался как корутинный, до Python 3.7 он возвращал
Future. Начиная с Python 3.7 это методasync def.
-
coroutine loop.sock_sendto(sock, data, address) -
Отправить дейтаграмму из sock по адресу address. Асинхронная версия
socket.sendto().Возвращает количество отправленных байт.
sock должен быть неблокирующим сокетом.
Добавлено в версии 3.11.
-
coroutine loop.sock_connect(sock, address) -
Подключить sock к удалённому сокету по адресу address.
Асинхронная версия
socket.connect().sock должен быть неблокирующим сокетом.
Изменено в версии 3.5.2:
addressбольше не требуется разрешать.sock_connectпопробует проверить, разрешён ли уже адрес address, вызвавsocket.inet_pton(). Если нет, для разрешения адреса address будет использованloop.getaddrinfo().См. также
-
coroutine loop.sock_accept(sock) -
Принять соединение. Реализован по образцу блокирующего метода
socket.accept().Сокет должен быть привязан к адресу и ожидать входящих соединений. Возвращаемое значение — пара
(conn, address), где conn — новый объект сокета, пригодный для отправки и получения данных по соединению, а address — адрес, к которому привязан сокет на другом конце соединения.sock должен быть неблокирующим сокетом.
Изменено в версии 3.7: Хотя этот метод всегда документировался как корутинный, до Python 3.7 он возвращал
Future. Начиная с Python 3.7 это методasync def.См. также
-
coroutine loop.sock_sendfile(sock, file, offset=0, count=None, *, fallback=True) -
Отправить файл, по возможности используя высокопроизводительный вызов
os.sendfile. Возвращает общее количество отправленных байт.Асинхронная версия
socket.sendfile().sock должен быть неблокирующим сокетом
socket.SOCK_STREAMsocket.file должен быть обычным файловым объектом, открытым в двоичном режиме.
offset указывает, с какого места начинать чтение файла. Если задан параметр count, он определяет общее количество байт для передачи, а не отправку файла до достижения EOF. Позиция в файле обновляется всегда, даже если этот метод вызывает ошибку; для получения фактического количества отправленных байт можно использовать
file.tell().Если fallback задан как
True, asyncio вручную читает и отправляет файл, когда платформа не поддерживает системный вызов sendfile (например, в Windows или при использовании SSL-сокета в Unix).Вызывает
SendfileNotAvailableError, если система не поддерживает системный вызов sendfile и fallback равенFalse.sock должен быть неблокирующим сокетом.
Добавлено в версии 3.7.
DNS
-
coroutine loop.getaddrinfo(host, port, *, family=0, type=0, proto=0, flags=0) -
Асинхронная версия
socket.getaddrinfo().
-
coroutine loop.getnameinfo(sockaddr, flags=0) -
Асинхронная версия
socket.getnameinfo().
Изменено в версии 3.7: В документации всегда указывалось, что методы getaddrinfo и getnameinfo возвращают корутину, однако до Python 3.7 фактически они возвращали объекты asyncio.Future. Начиная с Python 3.7 оба метода являются корутинами.
Работа с каналами
-
coroutine loop.connect_read_pipe(protocol_factory, pipe) -
Зарегистрировать читающий конец pipe в цикле событий.
protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола asyncio.
pipe — это объект, подобный файлу.
Возвращает пару
(transport, protocol), где transport поддерживает интерфейсReadTransport, а protocol — объект, созданный с помощью protocol_factory.В цикле событий
SelectorEventLoopдля pipe устанавливается неблокирующий режим.
-
coroutine loop.connect_write_pipe(protocol_factory, pipe) -
Зарегистрировать записывающий конец pipe в цикле событий.
protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола asyncio.
pipe — это объект, подобный файлу.
Возвращает пару
(transport, protocol), где transport поддерживает интерфейсWriteTransport, а protocol — объект, созданный с помощью protocol_factory.В цикле событий
SelectorEventLoopдля pipe устанавливается неблокирующий режим.
Примечание
SelectorEventLoop не поддерживает приведённые выше методы в Windows. В Windows вместо него используйте ProactorEventLoop.
См. также
Сигналы Unix
-
loop.add_signal_handler(signum, callback, *args) -
Назначить callback обработчиком сигнала signum.
Функция обратного вызова будет вызвана циклом loop наряду с другими поставленными в очередь функциями обратного вызова и готовыми к выполнению корутинами этого цикла событий. В отличие от обработчиков сигналов, зарегистрированных с помощью
signal.signal(), функция обратного вызова, зарегистрированная этой функцией, может взаимодействовать с циклом событий.Вызывает
ValueError, если номер сигнала недопустим или его нельзя перехватить. ВызываетRuntimeError, если при настройке обработчика возникла проблема.Используйте
functools.partial()для передачи именованных аргументов в callback.Как и
signal.signal(), эту функцию необходимо вызывать в главном потоке.
-
loop.remove_signal_handler(sig) -
Удалить обработчик сигнала sig.
Возвращает
True, если обработчик сигнала был удалён, илиFalse, если для указанного сигнала обработчик не был задан.Доступность: Unix.
См. также
Модуль signal.
Выполнение кода в пулах потоков или процессов
-
awaitable loop.run_in_executor(executor, func, *args) -
Запланировать вызов func в указанном исполнителе.
Аргумент executor должен быть экземпляром
concurrent.futures.Executor. Если executor равенNone, используется исполнитель по умолчанию.Пример:
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()).
-
loop.get_exception_handler() -
Возвращает текущий обработчик исключений или
None, если пользовательский обработчик исключений не задан.Добавлено в версии 3.5.2.
-
loop.default_exception_handler(context) -
Обработчик исключений по умолчанию.
Вызывается при возникновении исключения, если обработчик исключений не задан. Его может вызвать пользовательский обработчик исключений, который хочет передать обработку обработчику по умолчанию.
Параметр context имеет то же значение, что и в
call_exception_handler().
-
loop.call_exception_handler(context) -
Вызвать текущий обработчик исключений цикла событий.
context — объект
dict, содержащий следующие ключи (в будущих версиях Python могут быть добавлены новые ключи):- ‘message’: сообщение об ошибке;
- ‘exception’ (необязательный): объект исключения;
- ‘future’ (необязательный): экземпляр
asyncio.Future; - ‘task’ (необязательный): экземпляр
asyncio.Task; - ‘handle’ (необязательный): экземпляр
asyncio.Handle; - ‘protocol’ (необязательный): экземпляр протокола;
- ‘transport’ (необязательный): экземпляр транспорта;
- ‘socket’ (необязательный): экземпляр
socket.socket; -
- ‘asyncgen’ (необязательный): асинхронный генератор, вызвавший
-
исключение.
Примечание
Не следует переопределять этот метод в подклассах циклов событий. Для пользовательской обработки исключений используйте метод
set_exception_handler().
Включение режима отладки
-
loop.get_debug() -
Получить состояние режима отладки (
bool) цикла событий.По умолчанию установлено значение
True, если переменная средыPYTHONASYNCIODEBUGзадана непустой строкой, иFalseв противном случае.
-
loop.set_debug(enabled: bool) -
Установить режим отладки цикла событий.
Изменено в версии 3.7: Теперь для включения режима отладки также можно использовать новый режим разработки Python.
-
loop.slow_callback_duration -
Этот атрибут позволяет задать минимальную продолжительность выполнения в секундах, при которой вызов считается «медленным». Если включён режим отладки, медленные функции обратного вызова записываются в журнал.
Значение по умолчанию — 100 миллисекунд.
См. также
Запуск подпроцессов
Методы, описанные в этом подразделе, относятся к низкоуровневым. В обычном коде с async/await вместо них рекомендуется использовать высокоуровневые вспомогательные функции asyncio.create_subprocess_shell() и asyncio.create_subprocess_exec().
Примечание
В Windows стандартный цикл событий ProactorEventLoop поддерживает подпроцессы, тогда как SelectorEventLoop — нет. Подробности см. в разделе Поддержка подпроцессов в Windows.
-
coroutine loop.subprocess_exec(protocol_factory, *args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) -
Создаёт подпроцесс из одного или нескольких строковых аргументов, заданных параметром args.
args должен быть списком строк, представленных в виде:
-
str; - или
bytes, закодированных в кодировке файловой системы.
Первая строка задаёт исполняемую программу, а остальные строки — аргументы. Вместе строковые аргументы образуют
argvпрограммы.Это похоже на вызов класса стандартной библиотеки
subprocess.Popenсshell=Falseи списком строк в качестве первого аргумента; однакоPopenпринимает один аргумент — список строк, а subprocess_exec принимает несколько строковых аргументов.protocol_factory должен быть вызываемым объектом, возвращающим подкласс класса
asyncio.SubprocessProtocol.Другие параметры:
-
stdin может принимать одно из следующих значений:
- файлоподобный объект, представляющий канал, подключаемый к стандартному потоку ввода подпроцесса с помощью
connect_write_pipe() - константа
subprocess.PIPE(значение по умолчанию), которая создаст и подключит новый канал; - значение
None, которое заставит подпроцесс унаследовать файловый дескриптор этого процесса; - константа
subprocess.DEVNULL, указывающая, что будет использоваться специальный файлos.devnull
- файлоподобный объект, представляющий канал, подключаемый к стандартному потоку ввода подпроцесса с помощью
-
stdout может принимать одно из следующих значений:
- файлоподобный объект, представляющий канал, подключаемый к стандартному потоку вывода подпроцесса с помощью
connect_write_pipe() - константа
subprocess.PIPE(значение по умолчанию), которая создаст и подключит новый канал; - значение
None, которое заставит подпроцесс унаследовать файловый дескриптор этого процесса; - константа
subprocess.DEVNULL, указывающая, что будет использоваться специальный файлos.devnull
- файлоподобный объект, представляющий канал, подключаемый к стандартному потоку вывода подпроцесса с помощью
-
stderr может принимать одно из следующих значений:
- файлоподобный объект, представляющий канал, подключаемый к стандартному потоку ошибок подпроцесса с помощью
connect_write_pipe() - константа
subprocess.PIPE(значение по умолчанию), которая создаст и подключит новый канал; - значение
None, которое заставит подпроцесс унаследовать файловый дескриптор этого процесса; - константа
subprocess.DEVNULL, указывающая, что будет использоваться специальный файлos.devnull - константа
subprocess.STDOUT, которая подключит стандартный поток ошибок к стандартному потоку вывода процесса
- файлоподобный объект, представляющий канал, подключаемый к стандартному потоку ошибок подпроцесса с помощью
-
Все остальные именованные аргументы без интерпретации передаются в
subprocess.Popen, за исключением bufsize, universal_newlines, shell, text, encoding и errors, которые не следует указывать.API подпроцессов
asyncioне поддерживает декодирование потоков в текст. Для преобразования байтов, возвращаемых потоком, в текст можно использоватьbytes.decode().
Документацию по другим аргументам см. в описании конструктора класса
subprocess.Popen.Возвращает пару объектов
(transport, protocol), где transport соответствует базовому классуasyncio.SubprocessTransport, а protocol — объект, созданный с помощью protocol_factory. -
-
coroutine loop.subprocess_shell(protocol_factory, cmd, *, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) -
Создаёт подпроцесс из cmd, который может быть строкой
strили строкойbytes, закодированной в кодировке файловой системы, используя синтаксис командной оболочки данной платформы.Это похоже на вызов класса стандартной библиотеки
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().-
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(), чтобы дождаться закрытия сервера.
-
get_loop() -
Возвращает цикл событий, связанный с объектом сервера.
Добавлено в версии 3.7.
-
coroutine start_serving() -
Начинает принимать подключения.
Этот метод идемпотентен, поэтому его можно вызывать, даже если сервер уже обслуживает подключения.
Параметр start_serving, указываемый только по имени, в функциях
loop.create_server()иasyncio.start_server()позволяет создать объект Server, который изначально не принимает подключения. В этом случае для начала приёма подключений сервером можно использоватьServer.start_serving()илиServer.serve_forever().Добавлено в версии 3.7.
-
coroutine 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.
-
coroutine wait_closed() -
Ожидает завершения метода
close().
-
sockets -
Список объектов, подобных сокетам,
asyncio.trsock.TransportSocket, на которых сервер ожидает подключения.Изменено в версии 3.7: До Python 3.7
Server.socketsвозвращал напрямую внутренний список серверных сокетов. В версии 3.7 возвращается копия этого списка.
-
Реализации цикла событий
В asyncio входят две разные реализации цикла событий: SelectorEventLoop и ProactorEventLoop.
По умолчанию asyncio настроен на использование SelectorEventLoop в Unix и ProactorEventLoop в Windows.
-
class asyncio.SelectorEventLoop -
Цикл событий, основанный на модуле
selectors.Использует наиболее эффективный селектор, доступный на данной платформе. Также можно вручную настроить конкретную реализацию селектора:
import asyncio import selectors class MyPolicy(asyncio.DefaultEventLoopPolicy): def new_event_loop(self): selector = selectors.SelectSelector() return asyncio.SelectorEventLoop(selector) asyncio.set_event_loop_policy(MyPolicy())Доступность: Unix, Windows.
-
class asyncio.ProactorEventLoop -
Цикл событий для Windows, использующий «порты завершения ввода-вывода» (IOCP).
Доступность: Windows.
-
class asyncio.AbstractEventLoop -
Абстрактный базовый класс для циклов событий, совместимых с asyncio.
В разделе Методы цикла событий перечислены все методы, которые должны быть определены в альтернативной реализации
AbstractEventLoop.
Примеры
Обратите внимание, что во всех примерах этого раздела специально показано использование низкоуровневых API цикла событий, таких как loop.run_forever() и loop.call_soon(). В современных приложениях asyncio редко возникает необходимость писать код таким образом; рассмотрите возможность использования высокоуровневых функций, например asyncio.run().
Привет, мир с call_soon()
Пример использования метода loop.call_soon() для планирования обратного вызова. Обратный вызов выводит "Hello World", а затем останавливает цикл событий:
import asyncio
def hello_world(loop):
"""A callback to print 'Hello World' and stop the event loop"""
print('Hello World')
loop.stop()
loop = asyncio.new_event_loop()
# Schedule a call to hello_world()
loop.call_soon(hello_world, loop)
# Blocking call interrupted by loop.stop()
try:
loop.run_forever()
finally:
loop.close()
См. также
Похожий пример «Привет, мир», созданный с помощью сопрограммы и функции run().
Отображение текущей даты с call_later()
Пример обратного вызова, который каждую секунду отображает текущую дату. Обратный вызов использует метод loop.call_later(), чтобы запланировать собственный повторный вызов через 5 секунд, а затем останавливает цикл событий:
import asyncio
import datetime
def display_date(end_time, loop):
print(datetime.datetime.now())
if (loop.time() + 1.0) < end_time:
loop.call_later(1, display_date, end_time, loop)
else:
loop.stop()
loop = asyncio.new_event_loop()
# Schedule the first call to display_date()
end_time = loop.time() + 5.0
loop.call_soon(display_date, end_time, loop)
# Blocking call interrupted by loop.stop()
try:
loop.run_forever()
finally:
loop.close()
См. также
Похожий пример с текущей датой, созданный с помощью сопрограммы и функции run().
Ожидание событий чтения для файлового дескриптора
Ожидание получения данных файловым дескриптором с помощью метода loop.add_reader(), после чего цикл событий закрывается:
import asyncio
from socket import socketpair
# Create a pair of connected file descriptors
rsock, wsock = socketpair()
loop = asyncio.new_event_loop()
def reader():
data = rsock.recv(100)
print("Received:", data.decode())
# We are done: unregister the file descriptor
loop.remove_reader(rsock)
# Stop the event loop
loop.stop()
# Register the file descriptor for read event
loop.add_reader(rsock, reader)
# Simulate the reception of data from the network
loop.call_soon(wsock.send, 'abc'.encode())
try:
# Run the event loop
loop.run_forever()
finally:
# We are done. Close sockets and the event loop.
rsock.close()
wsock.close()
loop.close()
См. также
- Похожий пример с использованием транспортов, протоколов и метода
loop.create_connection(). - Ещё один похожий пример с использованием высокоуровневой функции
asyncio.open_connection()и потоков.
Установка обработчиков сигналов SIGINT и SIGTERM
(Этот пример signals работает только в Unix.)
Регистрация обработчиков сигналов SIGINT и SIGTERM с помощью метода loop.add_signal_handler():
import asyncio
import functools
import os
import signal
def ask_exit(signame, loop):
print("got signal %s: exit" % signame)
loop.stop()
async def main():
loop = asyncio.get_running_loop()
for signame in {'SIGINT', 'SIGTERM'}:
loop.add_signal_handler(
getattr(signal, signame),
functools.partial(ask_exit, signame, loop))
await asyncio.sleep(3600)
print("Event loop running for 1 hour, press Ctrl+C to interrupt.")
print(f"pid {os.getpid()}: send SIGINT or SIGTERM to exit.")
asyncio.run(main())
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.11/library/asyncio-eventloop.html