# політики

An event loop policy is a global object used to get and set the current event loop, as well as create new event loops. The default policy can be replaced with built-in alternatives to use different event loop implementations, or substituted by a custom policy that can override these behaviors.

The policy object gets and sets a separate event loop per context. This is per-thread by default, though custom policies could define context differently.

Custom event loop policies can control the behavior of `get_event_loop()`, `set_event_loop()`, and `new_event_loop()`.

Об’єкти політики мають реалізовувати 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` тепер використовується за замовчуванням.

  Примітка

  In Python versions 3.10.9, 3.11.1 and 3.12 the `get_event_loop()` method of the default asyncio policy emits a `DeprecationWarning` if there is no running event loop and no current loop is set. In some future Python release this will become an error.

class asyncio.WindowsSelectorEventLoopPolicy

  Альтернативна політика циклу подій, яка використовує реалізацію циклу подій `SelectorEventLoop`.

  Availability: Windows.

class asyncio.WindowsProactorEventLoopPolicy

  Альтернативна політика циклу подій, яка використовує реалізацію циклу подій `ProactorEventLoop`.

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