політики

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