Цикл событий
Исходный код: Lib/asyncio/events.py, Lib/asyncio/base_events.py
Предисловие
Цикл событий — основа каждого приложения asyncio. Циклы событий выполняют асинхронные задачи и обратные вызовы, выполняют операции сетевого ввода-вывода и запускают подпроцессы.
Разработчикам приложений обычно следует использовать высокоуровневые функции asyncio, например asyncio.run(), и редко обращаться к объекту цикла или вызывать его методы. Этот раздел предназначен главным образом для авторов низкоуровневого кода, библиотек и фреймворков, которым требуется более точный контроль над поведением цикла событий.
Получение цикла событий
Для получения, установки или создания цикла событий можно использовать следующие низкоуровневые функции:
-
asyncio.get_running_loop() -
Возвращает работающий цикл событий в текущем потоке ОС.
Вызывает
RuntimeError, если работающего цикла событий нет.Эту функцию можно вызывать только из сопрограммы или обратного вызова.
Добавлено в версии 3.7.
-
asyncio.get_event_loop() -
Получает текущий цикл событий.
При вызове из сопрограммы или обратного вызова (например, запланированного с помощью call_soon или аналогичного API) эта функция всегда возвращает работающий цикл событий.
Если работающий цикл событий не установлен, функция возвращает результат вызова
get_event_loop_policy().get_event_loop().Поскольку поведение этой функции довольно сложное (особенно при использовании пользовательских политик цикла событий), в сопрограммах и обратных вызовах предпочтительнее использовать функцию
get_running_loop(), а неget_event_loop().Как отмечалось выше, рассмотрите возможность использования высокоуровневой функции
asyncio.run()вместо ручного создания и закрытия цикла событий с помощью этих низкоуровневых функций.Устарела с версии 3.12: Если текущий цикл событий отсутствует, выдается предупреждение об устаревании. В одном из будущих выпусков Python это станет ошибкой.
-
asyncio.set_event_loop(loop) -
Устанавливает loop в качестве текущего цикла событий для текущего потока ОС.
-
asyncio.new_event_loop() -
Создает и возвращает новый объект цикла событий.
Обратите внимание, что поведение функций get_event_loop(), set_event_loop() и new_event_loop() можно изменить, установив пользовательскую политику цикла событий.
Содержание
Эта страница документации содержит следующие разделы:
- В разделе Методы цикла событий приведена справочная документация по API цикла событий;
- В разделе Объекты-обработчики обратных вызовов описаны экземпляры
HandleиTimerHandle, возвращаемые методами планирования, такими какloop.call_soon()иloop.call_later(); - В разделе Объекты сервера описаны типы, возвращаемые методами цикла событий, например
loop.create_server(); - В разделе Реализации цикла событий описаны классы
SelectorEventLoopиProactorEventLoop; - В разделе Примеры показано, как работать с некоторыми API цикла событий.
Методы цикла событий
Циклы событий предоставляют низкоуровневые API для выполнения следующих действий:
- Запуск и остановка цикла
- Планирование обратных вызовов
- Планирование отложенных обратных вызовов
- Создание Future и Task
- Открытие сетевых соединений
- Создание сетевых серверов
- Передача файлов
- Переход на TLS
- Отслеживание файловых дескрипторов
- Непосредственная работа с объектами сокетов
- DNS
- Работа с каналами
- Сигналы Unix
- Выполнение кода в пулах потоков или процессов
- API обработки ошибок
- Включение режима отладки
- Запуск подпроцессов
Запуск и остановка цикла
-
loop.run_until_complete(future) -
Выполняет цикл до завершения future (экземпляра
Future).Если аргумент является объектом сопрограммы, он неявно планируется для выполнения в виде
asyncio.Task.Возвращает результат Future или вызывает его исключение.
-
loop.run_forever() -
Выполняет цикл событий, пока не будет вызван
stop().Если
stop()вызван до вызоваrun_forever(), цикл один раз опросит селектор ввода-вывода с нулевым временем ожидания, выполнит все обратные вызовы, запланированные в ответ на события ввода-вывода (а также уже запланированные), а затем завершит работу.Если
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))
Использовать объекты 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 и Task
-
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, если используется фабрика по умолчанию.
Открытие сетевых подключений
-
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: Для всех подключений TCP по умолчанию устанавливается параметр сокета socket.TCP_NODELAY.
Изменено в версии 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(). -
remote_addr, если указан, представляет собой кортеж
(remote_host, remote_port), используемый для подключения сокета к удалённому адресу. Значения remote_host и remote_port определяются с помощьюgetaddrinfo(). -
family, proto, flags — необязательные семейство адресов, протокол и флаги, передаваемые в
getaddrinfo()для разрешения имени host. Если они указаны, все эти значения должны быть целыми числами — соответствующими константами модуляsocket. - reuse_port указывает ядру разрешить привязку этой конечной точки к тому же порту, что и у других существующих конечных точек, при условии, что при их создании для всех был установлен этот флаг. Этот параметр не поддерживается в Windows и некоторых системах Unix. Если константа socket.SO_REUSEPORT не определена, эта возможность не поддерживается.
- allow_broadcast указывает ядру разрешить этой конечной точке отправлять сообщения на широковещательный адрес.
-
sock можно указать, чтобы использовать существующий, уже подключённый объект
socket.socketв качестве транспорта. Если он указан, аргументы local_addr и remote_addr следует опустить (они должны иметь значениеNone).Примечание
Аргумент sock передаёт созданному транспорту владение сокетом. Чтобы закрыть сокет, вызовите метод
close()транспорта.
См. примеры протокола UDP-клиента эхо-сервера и протокола UDP-сервера эхо-сервера.
Изменено в версии 3.4.4: Добавлены параметры family, proto, flags, reuse_address, reuse_port, allow_broadcast и sock.
Изменено в версии 3.8: Добавлена поддержка Windows.
Изменено в версии 3.8.1: Параметр reuse_address больше не поддерживается, поскольку использование socket.SO_REUSEADDR создаёт значительный риск для безопасности UDP. При явной передаче
reuse_address=Trueбудет вызвано исключение.Если несколько процессов с разными UID привязывают сокеты к одному и тому же адресу UDP-сокета с помощью
SO_REUSEADDR, входящие пакеты могут случайным образом распределяться между сокетами.На поддерживаемых платформах вместо аналогичной функциональности можно использовать reuse_port. При использовании reuse_port применяется socket.SO_REUSEPORT, который специально предотвращает привязку сокетов к одному адресу сокета процессами с разными UID.
Изменено в версии 3.11: Параметр reuse_address, отключённый начиная с Python 3.8.1, 3.7.6 и 3.6.10, полностью удалён.
-
local_addr, если указан, представляет собой кортеж
-
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, ssl_handshake_timeout=None, ssl_shutdown_timeout=None, start_serving=True) -
Создать TCP-сервер (тип сокета
SOCK_STREAM), прослушивающий адрес host и порт port.Возвращает объект
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.
-
ssl_handshake_timeout — время в секундах ожидания завершения рукопожатия TLS до прерывания подключения (для TLS-сервера).
60.0секунд, если указаноNone(значение по умолчанию). -
ssl_shutdown_timeout — время в секундах ожидания завершения отключения SSL до прерывания подключения.
30.0секунд, если указаноNone(значение по умолчанию). -
Если для параметра start_serving задано
True(значение по умолчанию), созданный сервер сразу начинает принимать подключения. Если заданоFalse, пользователь должен дождаться выполненияServer.start_serving()илиServer.serve_forever(), чтобы сервер начал принимать подключения.
Изменено в версии 3.5: Добавлена поддержка SSL/TLS в
ProactorEventLoop.Изменено в версии 3.5.1: Параметр host может быть последовательностью строк.
Изменено в версии 3.6: Добавлены параметры ssl_handshake_timeout и start_serving. Для всех подключений TCP по умолчанию устанавливается параметр сокета socket.TCP_NODELAY.
Изменено в версии 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) -
Аналогичен
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.
-
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 и вставить его между транспортом и протоколом. Кодировщик/декодировщик реализует как протокол для транспорта, так и транспорт для протокола.
Вернуть созданный экземпляр с двумя интерфейсами. После await протокол должен перестать использовать исходный транспорт и взаимодействовать только с возвращённым объектом, поскольку кодировщик кэширует данные со стороны протокола и время от времени обменивается дополнительными пакетами сеанса TLS с транспортом.
В некоторых ситуациях (например, когда переданный транспорт уже закрывается) может быть возвращено
None.Параметры:
-
Экземпляры transport и protocol, которые возвращают такие методы, как
create_server()иcreate_connection(). -
sslcontext: настроенный экземпляр
SSLContext. -
server_side: передайте
True, если обновляется соединение на стороне сервера (например, соединение, созданное методомcreate_server()). - server_hostname: задаёт или переопределяет имя узла, с которым будет сопоставляться сертификат целевого сервера.
-
ssl_handshake_timeout — время в секундах, в течение которого ожидается завершение рукопожатия TLS перед прерыванием соединения.
60.0секунд, если указаноNone(значение по умолчанию). -
ssl_shutdown_timeout — время в секундах, в течение которого ожидается завершение закрытия SSL перед прерыванием соединения.
30.0секунд, если указаноNone(значение по умолчанию).
Добавлено в версии 3.7.
Изменено в версии 3.11: Добавлен параметр ssl_shutdown_timeout.
-
Экземпляры 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 с указанными аргументами, когда 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) -
Получить до nbytes байт из sock. Асинхронный вариант
socket.recv().Возвращает полученные данные в виде объекта bytes.
sock должен быть неблокирующим сокетом.
Изменено в версии 3.7: Хотя в документации этот метод всегда описывался как метод-корутина, в выпусках до Python 3.7 он возвращал
Future. Начиная с Python 3.7 это методasync def.
-
async loop.sock_recv_into(sock, buf) -
Получить данные из sock в буфер buf. Метод создан по образцу блокирующего метода
socket.recv_into().Возвращает количество байт, записанных в буфер.
sock должен быть неблокирующим сокетом.
Добавлено в версии 3.7.
-
async loop.sock_recvfrom(sock, bufsize) -
Получить из sock датаграмму размером до bufsize. Асинхронный вариант
socket.recvfrom().Возвращает кортеж (полученные данные, удалённый адрес).
sock должен быть неблокирующим сокетом.
Добавлено в версии 3.11.
-
async loop.sock_recvfrom_into(sock, buf, nbytes=0) -
Получить из sock датаграмму размером до nbytes в buf. Асинхронный вариант
socket.recvfrom_into().Возвращает кортеж (количество полученных байт, удалённый адрес).
sock должен быть неблокирующим сокетом.
Добавлено в версии 3.11.
-
async loop.sock_sendall(sock, data) -
Отправить data в сокет sock. Асинхронный вариант
socket.sendall().Этот метод продолжает отправлять данные в сокет, пока все данные из data не будут отправлены или не произойдёт ошибка. В случае успеха возвращается
None. В случае ошибки возникает исключение. Кроме того, невозможно определить, какое количество данных, если таковое имеется, было успешно обработано принимающей стороной соединения.sock должен быть неблокирующим сокетом.
Изменено в версии 3.7: Хотя в документации этот метод всегда описывался как метод-корутина, до Python 3.7 он возвращал
Future. Начиная с Python 3.7 это методasync def.
-
async loop.sock_sendto(sock, data, address) -
Отправить датаграмму из sock по адресу address. Асинхронный вариант
socket.sendto().Возвращает количество отправленных байт.
sock должен быть неблокирующим сокетом.
Добавлено в версии 3.11.
-
async loop.sock_connect(sock, address) -
Подключить sock к удалённому сокету по адресу address.
Асинхронный вариант
socket.connect().sock должен быть неблокирующим сокетом.
Изменено в версии 3.5.2:
addressбольше не требуется разрешать.sock_connectпопытается проверить, разрешён ли уже адрес address, вызвавsocket.inet_pton(). Если нет, для разрешения адреса address будет использованloop.getaddrinfo().См. также
-
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 — это объект, подобный файлу.
Возвращает пару
(transport, protocol), где transport поддерживает интерфейсReadTransport, а protocol — объект, созданный protocol_factory.В цикле событий
SelectorEventLoopдля pipe устанавливается неблокирующий режим.
-
async loop.connect_write_pipe(protocol_factory, pipe) -
Зарегистрировать пишущий конец pipe в цикле событий.
protocol_factory должен быть вызываемым объектом, возвращающим реализацию протокола asyncio.
pipe — это объект, подобный файлу.
Возвращает пару
(transport, protocol), где transport поддерживает интерфейсWriteTransport, а protocol — объект, созданный protocol_factory.В цикле событий
SelectorEventLoopдля pipe устанавливается неблокирующий режим.
Примечание
SelectorEventLoop не поддерживает указанные выше методы в Windows. В Windows вместо него используйте ProactorEventLoop.
См. также
Сигналы Unix
-
loop.add_signal_handler(signum, callback, *args) -
Назначить callback обработчиком сигнала signum.
Обратный вызов будет вызываться циклом loop наряду с другими обратными вызовами в очереди и готовыми к выполнению корутинами этого цикла событий. В отличие от обработчиков сигналов, зарегистрированных с помощью
signal.signal(), обратному вызову, зарегистрированному этой функцией, разрешено взаимодействовать с циклом событий.Вызывает
ValueError, если номер сигнала недопустим или сигнал нельзя перехватить. ВызываетRuntimeError, если при настройке обработчика возникает проблема.Используйте
functools.partial()для передачи именованных аргументов в callback.Как и
signal.signal(), эту функцию необходимо вызывать в главном потоке.
-
loop.remove_signal_handler(sig) -
Удалить обработчик сигнала sig.
Возвращает
True, если обработчик сигнала был удалён, илиFalse, если для указанного сигнала обработчик не был задан.Доступность: Unix.
См. также
Модуль signal.
Выполнение кода в пулах потоков или процессов
-
awaitable loop.run_in_executor(executor, func, *args) -
Запланировать вызов func в указанном исполнителе.
Аргумент executor должен быть экземпляром
concurrent.futures.Executor. Если executor равенNone, используется исполнитель по умолчанию. Исполнитель по умолчанию можно задать с помощьюloop.set_default_executor(); в противном случаеconcurrent.futures.ThreadPoolExecutorбудет создан при необходимости и использован методомrun_in_executor().Пример:
import asyncio import concurrent.futures def blocking_io(): # File operations (such as logging) can block the # event loop: run them in a thread pool. with open('/dev/urandom', 'rb') as f: return f.read(100) def cpu_bound(): # CPU-bound operations will block the event loop: # in general it is preferable to run them in a # process pool. return sum(i * i for i in range(10 ** 7)) async def main(): loop = asyncio.get_running_loop() ## Options: # 1. Run in the default loop's executor: result = await loop.run_in_executor( None, blocking_io) print('default thread pool', result) # 2. Run in a custom thread pool: with concurrent.futures.ThreadPoolExecutor() as pool: result = await loop.run_in_executor( pool, blocking_io) print('custom thread pool', result) # 3. Run in a custom process pool: with concurrent.futures.ProcessPoolExecutor() as pool: result = await loop.run_in_executor( pool, cpu_bound) print('custom process pool', result) if __name__ == '__main__': asyncio.run(main())Обратите внимание: для варианта 3 требуется защита точки входа (
if __name__ == '__main__') из-за особенностейmultiprocessing, используемогоProcessPoolExecutor. См. раздел Безопасный импорт главного модуля.Этот метод возвращает объект
asyncio.Future.Используйте
functools.partial()для передачи именованных аргументов в func.Изменено в версии 3.5.3:
loop.run_in_executor()больше не настраиваетmax_workersсоздаваемого им исполнителя пула потоков, оставляя установку значения по умолчанию самому исполнителю пула потоков (ThreadPoolExecutor).
-
loop.set_default_executor(executor) -
Задать executor в качестве исполнителя по умолчанию, используемого методом
run_in_executor(). executor должен быть экземпляромThreadPoolExecutor.Изменено в версии 3.11: executor должен быть экземпляром
ThreadPoolExecutor.
API обработки ошибок
Позволяет настраивать обработку исключений в цикле событий.
-
loop.set_exception_handler(handler) -
Задать handler в качестве нового обработчика исключений цикла событий.
Если handler равен
None, будет задан обработчик исключений по умолчанию. В противном случае handler должен быть вызываемым объектом с сигнатурой, соответствующей(loop, context), гдеloop— ссылка на активный цикл событий, аcontext— объектdict, содержащий сведения об исключении (подробности о контексте см. в документацииcall_exception_handler()).Если обработчик вызывается от имени
TaskилиHandle, он выполняется вcontextvars.Contextэтой задачи или дескриптора обратного вызова.Изменено в версии 3.12: Обработчик может вызываться в
Contextзадачи или дескриптора, в котором возникло исключение.
-
loop.get_exception_handler() -
Возвращает текущий обработчик исключений или
None, если пользовательский обработчик исключений не задан.Добавлено в версии 3.5.2.
-
loop.default_exception_handler(context) -
Обработчик исключений по умолчанию.
Вызывается, когда происходит исключение и обработчик исключений не задан. Его может вызвать пользовательский обработчик исключений, который передаёт обработку обработчику по умолчанию.
Параметр context имеет то же значение, что и в
call_exception_handler().
-
loop.call_exception_handler(context) -
Вызвать текущий обработчик исключений цикла событий.
context — объект
dict, содержащий следующие ключи (в будущих версиях Python могут появиться новые ключи):- ‘message’: сообщение об ошибке;
- ‘exception’ (необязательный): объект исключения;
- ‘future’ (необязательный): экземпляр
asyncio.Future; - ‘task’ (необязательный): экземпляр
asyncio.Task; - ‘handle’ (необязательный): экземпляр
asyncio.Handle; - ‘protocol’ (необязательный): экземпляр протокола;
- ‘transport’ (необязательный): экземпляр транспорта;
- ‘socket’ (необязательный): экземпляр
socket.socket; -
- ‘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.
-
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(), чтобы дождаться закрытия сервера (и завершения всех соединений).
-
get_loop() -
Возвращает цикл событий, связанный с объектом сервера.
Добавлено в версии 3.7.
-
async start_serving() -
Начинает принимать соединения.
Этот метод идемпотентен, поэтому его можно вызвать, даже если сервер уже обслуживает запросы.
Параметр start_serving, задаваемый только по имени, в функциях
loop.create_server()иasyncio.start_server()позволяет создать объект Server, который изначально не принимает соединения. В этом случае для начала приёма соединений объектом Server можно использоватьServer.start_serving()илиServer.serve_forever().Добавлено в версии 3.7.
-
async serve_forever() -
Начинает принимать соединения и продолжает это делать, пока корутина не будет отменена. Отмена задачи
serve_foreverприводит к закрытию сервера.Этот метод можно вызвать, даже если сервер уже принимает соединения. Для одного объекта Server может существовать только одна задача
serve_forever.Пример:
async def client_connected(reader, writer): # Communicate with the client with # reader/writer streams. For example: await reader.readline() async def main(host, port): srv = await asyncio.start_server( client_connected, host, port) await srv.serve_forever() asyncio.run(main('127.0.0.1', 0))Добавлено в версии 3.7.
-
is_serving() -
Возвращает
True, если сервер принимает новые соединения.Добавлено в версии 3.7.
-
async wait_closed() -
Ожидает завершения метода
close()и закрытия всех активных соединений.
-
sockets -
Список объектов, подобных сокетам,
asyncio.trsock.TransportSocket, на которых сервер ожидает соединения.Изменено в версии 3.7: До Python 3.7
Server.socketsвозвращал непосредственно внутренний список серверных сокетов. В версии 3.7 возвращается копия этого списка.
-
Реализации цикла событий
В asyncio входят две различные реализации цикла событий: SelectorEventLoop и ProactorEventLoop.
По умолчанию asyncio настроен на использование 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().
Hello World с call_soon()
Пример использования метода loop.call_soon() для планирования обратного вызова. Обратный вызов выводит "Hello World", а затем останавливает цикл событий:
import asyncio
def hello_world(loop):
"""A callback to print 'Hello World' and stop the event loop"""
print('Hello World')
loop.stop()
loop = asyncio.new_event_loop()
# Schedule a call to hello_world()
loop.call_soon(hello_world, loop)
# Blocking call interrupted by loop.stop()
try:
loop.run_forever()
finally:
loop.close()
См. также
Похожий пример Hello World, созданный с помощью корутины и функции run().
Отображение текущей даты с помощью call_later()
Пример обратного вызова, отображающего текущую дату каждую секунду. Обратный вызов использует метод loop.call_later(), чтобы запланировать повторный вызов через 5 секунд, а затем останавливает цикл событий:
import asyncio
import datetime
def display_date(end_time, loop):
print(datetime.datetime.now())
if (loop.time() + 1.0) < end_time:
loop.call_later(1, display_date, end_time, loop)
else:
loop.stop()
loop = asyncio.new_event_loop()
# Schedule the first call to display_date()
end_time = loop.time() + 5.0
loop.call_soon(display_date, end_time, loop)
# Blocking call interrupted by loop.stop()
try:
loop.run_forever()
finally:
loop.close()
См. также
Похожий пример текущей даты, созданный с помощью корутины и функции run().
Ожидание событий чтения на файловом дескрипторе
Ожидает получения данных файловым дескриптором с помощью метода loop.add_reader(), а затем закрывает цикл событий:
import asyncio
from socket import socketpair
# Create a pair of connected file descriptors
rsock, wsock = socketpair()
loop = asyncio.new_event_loop()
def reader():
data = rsock.recv(100)
print("Received:", data.decode())
# We are done: unregister the file descriptor
loop.remove_reader(rsock)
# Stop the event loop
loop.stop()
# Register the file descriptor for read event
loop.add_reader(rsock, reader)
# Simulate the reception of data from the network
loop.call_soon(wsock.send, 'abc'.encode())
try:
# Run the event loop
loop.run_forever()
finally:
# We are done. Close sockets and the event loop.
rsock.close()
wsock.close()
loop.close()
См. также
- Похожий пример с использованием транспортов, протоколов и метода
loop.create_connection(). - Другой похожий пример с использованием высокоуровневой функции
asyncio.open_connection()и потоков.
Установка обработчиков сигналов SIGINT и SIGTERM
(Этот signals пример работает только в Unix.)
Зарегистрируйте обработчики сигналов SIGINT и SIGTERM с помощью метода loop.add_signal_handler():
import asyncio
import functools
import os
import signal
def ask_exit(signame, loop):
print("got signal %s: exit" % signame)
loop.stop()
async def main():
loop = asyncio.get_running_loop()
for signame in {'SIGINT', 'SIGTERM'}:
loop.add_signal_handler(
getattr(signal, signame),
functools.partial(ask_exit, signame, loop))
await asyncio.sleep(3600)
print("Event loop running for 1 hour, press Ctrl+C to interrupt.")
print(f"pid {os.getpid()}: send SIGINT or SIGTERM to exit.")
asyncio.run(main())
© 2001–2024 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.12/library/asyncio-eventloop.html