політики¶
An event loop policy is a global per-process object that controls the management of the event loop. Each event loop has a default policy, which can be changed and customized using the policy API.
A policy defines the notion of context and manages a separate event loop per context. The default policy defines context to be the current thread.
By using a custom event loop policy, the behavior of
get_event_loop()
, set_event_loop()
, and
new_event_loop()
functions can be customized.
Об’єкти політики мають реалізовувати API, визначені в AbstractEventLoopPolicy
абстрактному базовому класі.
Отримання та налаштування політики¶
Наступні функції можна використовувати для отримання та налаштування політики для поточного процесу:
-
asyncio.
get_event_loop_policy
()¶ Повернути поточну політику для всього процесу.
-
asyncio.
set_event_loop_policy
(policy)¶ Установіть поточну політику для всього процесу на policy.
Якщо policy встановлено на
None
, політика за замовчуванням буде відновлена.
Об’єкти політики¶
Базовий клас політики абстрактного циклу подій визначається наступним чином:
-
class
asyncio.
AbstractEventLoopPolicy
¶ Абстрактний базовий клас для асинхронних політик.
-
get_event_loop
()¶ Отримати цикл подій для поточного контексту.
Повертає об’єкт циклу подій, що реалізує інтерфейс
AbstractEventLoop
.Цей метод ніколи не повинен повертати
None
.Змінено в версії 3.6.
-
set_event_loop
(loop)¶ Встановіть для циклу подій для поточного контексту значення loop.
-
new_event_loop
()¶ Створити та повернути новий об’єкт циклу подій.
Цей метод ніколи не повинен повертати
None
.
-
get_child_watcher
()¶ Отримайте дочірній об’єкт спостереження за процесом.
Повертає об’єкт спостереження, що реалізує інтерфейс
AbstractChildWatcher
.Ця функція є специфічною для Unix.
-
set_child_watcher
(watcher)¶ Встановіть для поточного спостерігача дочірнього процесу значення watcher.
Ця функція є специфічною для Unix.
-
asyncio поставляється з такими вбудованими політиками:
-
class
asyncio.
DefaultEventLoopPolicy
¶ Стандартна асинхронна політика. Використовує
SelectorEventLoop
в Unix іProactorEventLoop
у Windows.Немає необхідності встановлювати стандартну політику вручну. asyncio налаштовано на автоматичне використання політики за замовчуванням.
Змінено в версії 3.8: У Windows
ProactorEventLoop
тепер використовується за замовчуванням.
-
class
asyncio.
WindowsSelectorEventLoopPolicy
¶ Альтернативна політика циклу подій, яка використовує реалізацію циклу подій
SelectorEventLoop
.Наявність: Windows.
-
class
asyncio.
WindowsProactorEventLoopPolicy
¶ Альтернативна політика циклу подій, яка використовує реалізацію циклу подій
ProactorEventLoop
.Наявність: Windows.
Спостерігачі процесів¶
Спостерігач процесів дозволяє налаштувати те, як цикл подій відстежує дочірні процеси в Unix. Зокрема, цикл подій повинен знати, коли завершився дочірній процес.
В asyncio дочірні процеси створюються за допомогою функцій create_subprocess_exec()
і loop.subprocess_exec()
.
asyncio визначає абстрактний базовий клас AbstractChildWatcher
, який повинні реалізувати дочірні спостерігачі, і має чотири різні реалізації: ThreadedChildWatcher
(налаштований для використання за замовчуванням), MultiLoopChildWatcher
, SafeChildWatcher
і FastChildWatcher
.
Дивіться також розділ Subprocess and Threads.
Наступні дві функції можна використовувати для налаштування реалізації спостерігача дочірніх процесів, що використовується циклом асинхронних подій:
-
asyncio.
get_child_watcher
()¶ Повертає поточний дочірній спостерігач для поточної політики.
-
asyncio.
set_child_watcher
(watcher)¶ Установіть для поточного дочірнього спостерігача значення watcher для поточної політики. watcher повинен реалізовувати методи, визначені в базовому класі
AbstractChildWatcher
.
Примітка
Реалізації сторонніх циклів подій можуть не підтримувати користувацькі дочірні спостерігачі. Для таких циклів подій використання set_child_watcher()
може бути заборонено або не матиме ефекту.
-
class
asyncio.
AbstractChildWatcher
¶ -
add_child_handler
(pid, callback, *args)¶ Зареєструвати нового дочірнього обробника.
Організуйте виклик
callback(pid, returncode, *args)
під час завершення процесу з PID, рівним pid. Зазначення іншого зворотного виклику для того самого процесу замінює попередній обробник.Функція callback має бути потокобезпечною.
-
remove_child_handler
(pid)¶ Видаляє обробник для процесу з PID рівним pid.
Функція повертає
True
, якщо обробник було успішно видалено,False
, якщо не було нічого для видалення.
-
attach_loop
(loop)¶ Приєднайте спостерігач до циклу подій.
Якщо спостерігач був раніше приєднаний до циклу подій, то він спочатку від’єднується перед приєднанням до нового циклу.
Примітка: цикл може бути
None
.
-
is_active
()¶ Повертає
True
, якщо спостерігач готовий до використання.Створення підпроцесу з неактивним поточним дочірнім спостерігачем викликає
RuntimeError
.Нове в версії 3.8.
-
close
()¶ Закрийте спостерігач.
Цей метод потрібно викликати, щоб переконатися, що базові ресурси очищені.
-
-
class
asyncio.
ThreadedChildWatcher
¶ Ця реалізація запускає новий потік очікування для кожного породження підпроцесу.
Він працює надійно, навіть якщо цикл асинхронних подій виконується в неосновному потоці ОС.
There is no noticeable overhead when handling a big number of children (O(1) each time a child terminates), but starting a thread per process requires extra memory.
Цей спостерігач використовується за замовчуванням.
Нове в версії 3.8.
-
class
asyncio.
MultiLoopChildWatcher
¶ Ця реалізація реєструє обробник сигналу
SIGCHLD
під час створення екземпляра. Це може порушити код третьої сторони, який встановлює спеціальний обробник для сигналуSIGCHLD
.Спостерігач уникає порушення інших процесів створення коду, явно опитуючи кожен процес за сигналом
SIGCHLD
.Немає обмежень для запуску підпроцесів з різних потоків після встановлення спостерігача.
The solution is safe but it has a significant overhead when handling a big number of processes (O(n) each time a
SIGCHLD
is received).Нове в версії 3.8.
-
class
asyncio.
SafeChildWatcher
¶ Ця реалізація використовує активний цикл подій з основного потоку для обробки сигналу
SIGCHLD
. Якщо основний потік не має запущеного циклу подій, інший потік не може породити підпроцес (виникаєRuntimeError
).Спостерігач уникає порушення інших процесів створення коду, явно опитуючи кожен процес за сигналом
SIGCHLD
.This solution is as safe as
MultiLoopChildWatcher
and has the same O(N) complexity but requires a running event loop in the main thread to work.
-
class
asyncio.
FastChildWatcher
¶ Ця реалізація збирає всі завершені процеси шляхом безпосереднього виклику
os.waitpid(-1)
, можливо, порушуючи інші процеси породження коду та чекаючи їх завершення.There is no noticeable overhead when handling a big number of children (O(1) each time a child terminates).
Для роботи цього рішення потрібен запущений цикл подій у головному потоці, як
SafeChildWatcher
.
-
class
asyncio.
PidfdChildWatcher
¶ Ця реалізація опитує дескриптори файлів процесу (pidfds) для очікування завершення дочірнього процесу. У деяких відношеннях
PidfdChildWatcher
є реалізацією дочірнього спостерігача «Золотовласка». Він не потребує сигналів чи потоків, не заважає жодним процесам, запущеним поза циклом подій, і масштабується лінійно залежно від кількості підпроцесів, запущених циклом подій. Основним недоліком є те, що pidfds є специфічними для Linux і працюють лише на останніх (5.3+) ядрах.Нове в версії 3.9.
Спеціальна політика¶
Щоб запровадити нову політику циклу подій, рекомендується створити підклас DefaultEventLoopPolicy
і перевизначити методи, для яких потрібна спеціальна поведінка, наприклад:
class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
def get_event_loop(self):
"""Get the event loop.
This may be None or an instance of EventLoop.
"""
loop = super().get_event_loop()
# Do something with loop ...
return loop
asyncio.set_event_loop_policy(MyEventLoopPolicy())