Документация Python неофициальный перевод

asyncio-policy.md

239 строк · 18.0 КБ · обычная страница · сырой текст · скачать

1> **Источник:** https://python-all.ru/3.13/library/asyncio-policy.html2>3> «Документация Python на русском» – неофициальный перевод официальной документации Python: версии от 2.6 до 3.16, полнотекстовый поиск, английский оригинал рядом с переводом. Эта Markdown-версия страницы предназначена для работы с LLM: вставьте её в ChatGPT, Claude или Cursor.45---67# Политики89Политика цикла событий – это глобальный объект, используемый для получения и установки текущего [цикла событий](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio-event-loop), а также для создания новых циклов событий. Стандартную политику можно [заменить](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio-policy-get-set) на [встроенные альтернативы](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio-policy-builtin) для использования других реализаций цикла событий или заменить [пользовательской политикой](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio-custom-policies), которая может переопределять это поведение.1011Объект [политики](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio-policy-objects) получает и устанавливает отдельный цикл событий для каждого *контекста*. По умолчанию это выполняется для каждого потока, хотя пользовательские политики могут определять *контекст* иначе.1213Пользовательские политики цикла событий могут управлять поведением [`get_event_loop()`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.get_event_loop), [`set_event_loop()`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.set_event_loop) и [`new_event_loop()`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.new_event_loop).1415Объекты политик должны реализовывать API, определённые в абстрактном базовом классе [`AbstractEventLoopPolicy`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.AbstractEventLoopPolicy).1617## Получение и установка политики1819Следующие функции можно использовать для получения и установки политики для текущего процесса:2021#### `asyncio.get_event_loop_policy()`2223Возвращает текущую политику для всего процесса.2425#### `asyncio.set_event_loop_policy(policy)`2627Устанавливает текущую политику для всего процесса в *policy*.2829Если для *policy* установлено значение `None`, восстанавливается стандартная политика.3031## Объекты политик3233Абстрактный базовый класс политики цикла событий определяется следующим образом:3435#### `class asyncio.AbstractEventLoopPolicy`3637Абстрактный базовый класс для политик asyncio.3839#### `get_event_loop()`4041Возвращает цикл событий для текущего контекста.4243Возвращает объект цикла событий, реализующий интерфейс [`AbstractEventLoop`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.AbstractEventLoop).4445Этот метод никогда не должен возвращать `None`.4647Изменено в версии 3.6.4849#### `set_event_loop(loop)`5051Устанавливает цикл событий для текущего контекста равным *loop*.5253#### `new_event_loop()`5455Создаёт и возвращает новый объект цикла событий.5657Этот метод никогда не должен возвращать `None`.5859#### `get_child_watcher()`6061Получить объект наблюдателя за дочерними процессами.6263Возвращает объект наблюдателя, реализующий [`AbstractChildWatcher`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.AbstractChildWatcher) интерфейс.6465Эта функция специфична для Unix.6667Устарело с версии 3.12.6869#### `set_child_watcher(watcher)`7071Устанавливает текущий наблюдатель за дочерними процессами на *watcher*.7273Эта функция специфична для Unix.7475Устарело с версии 3.12.7677asyncio включает следующие встроенные политики:7879#### `class asyncio.DefaultEventLoopPolicy`8081Политика asyncio по умолчанию. Использует [`SelectorEventLoop`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.SelectorEventLoop) в Unix и [`ProactorEventLoop`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.ProactorEventLoop) в Windows.8283Нет необходимости устанавливать политику по умолчанию вручную. asyncio настроена на автоматическое использование политики по умолчанию.8485Изменено в версии 3.8: В Windows [`ProactorEventLoop`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.ProactorEventLoop) теперь используется по умолчанию.8687Устарело с версии 3.12: Метод [`get_event_loop()`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.get_event_loop) политики asyncio по умолчанию теперь генерирует [`DeprecationWarning`](https://python-all.ru/3.13/library/exceptions.html#DeprecationWarning), если текущий цикл событий не задан и он решает создать его. В одном из будущих выпусков Python это станет ошибкой.8889#### `class asyncio.WindowsSelectorEventLoopPolicy`9091Альтернативная политика цикла событий, использующая реализацию цикла событий [`SelectorEventLoop`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.SelectorEventLoop).9293[Доступность](https://python-all.ru/3.13/library/intro.html#availability): Windows.9495#### `class asyncio.WindowsProactorEventLoopPolicy`9697Альтернативная политика цикла событий, использующая реализацию цикла событий [`ProactorEventLoop`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.ProactorEventLoop).9899[Доступность](https://python-all.ru/3.13/library/intro.html#availability): Windows.100101## Наблюдатели за процессами102103Наблюдатель за процессами позволяет настраивать, как цикл событий отслеживает дочерние процессы в Unix. В частности, циклу событий необходимо знать, когда дочерний процесс завершился.104105В asyncio дочерние процессы создаются с помощью функций [`create_subprocess_exec()`](https://python-all.ru/3.13/library/asyncio-subprocess.html#asyncio.create_subprocess_exec) и [`loop.subprocess_exec()`](https://python-all.ru/3.13/library/asyncio-eventloop.html#asyncio.loop.subprocess_exec).106107asyncio определяет абстрактный базовый класс [`AbstractChildWatcher`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.AbstractChildWatcher), который должны реализовывать наблюдатели за дочерними процессами, и имеет четыре реализации: [`ThreadedChildWatcher`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.ThreadedChildWatcher) (используется по умолчанию), [`MultiLoopChildWatcher`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.MultiLoopChildWatcher), [`SafeChildWatcher`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.SafeChildWatcher) и [`FastChildWatcher`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.FastChildWatcher).108109См. также раздел [Подпроцессы и потоки](https://python-all.ru/3.13/library/asyncio-subprocess.html#asyncio-subprocess-threads) .110111Следующие две функции можно использовать для настройки реализации наблюдателя за дочерними процессами, используемого циклом событий asyncio:112113#### `asyncio.get_child_watcher()`114115Возвращает текущий наблюдатель за дочерними процессами для текущей политики.116117Устарело с версии 3.12.118119#### `asyncio.set_child_watcher(watcher)`120121Устанавливает текущий наблюдатель за дочерними процессами на *watcher* для текущей политики. *watcher* должен реализовывать методы, определённые в базовом классе [`AbstractChildWatcher`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.AbstractChildWatcher).122123Устарело с версии 3.12.124125> **Примечание**126>127> Реализации циклов событий от сторонних разработчиков могут не поддерживать пользовательские наблюдатели за дочерними процессами. Для таких циклов событий использование [`set_child_watcher()`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.set_child_watcher) может быть запрещено или не иметь эффекта.128129#### `class asyncio.AbstractChildWatcher`130131#### `add_child_handler(pid, callback, *args)`132133Регистрирует новый обработчик дочернего процесса.134135Организует вызов `callback(pid, returncode, *args)` при завершении процесса с PID, равным *pid*. Указание другого колбэка для того же процесса заменяет предыдущий обработчик.136137Вызываемый объект *колбэк* должен быть потокобезопасным.138139#### `remove_child_handler(pid)`140141Удаляет обработчик для процесса с PID, равным *pid*.142143Функция возвращает `True`, если обработчик был успешно удалён, и `False`, если удалять было нечего.144145#### `attach_loop(loop)`146147Присоединяет наблюдатель к циклу событий.148149Если наблюдатель ранее был присоединён к циклу событий, то перед присоединением к новому циклу он сначала отсоединяется.150151Примечание: loop может быть `None`.152153#### `is_active()`154155Возвращает `True`, если наблюдатель готов к использованию.156157Запуск подпроцесса с *неактивным* текущим наблюдателем дочерних процессов вызывает [`RuntimeError`](https://python-all.ru/3.13/library/exceptions.html#RuntimeError).158159Добавлено в версии 3.8.160161#### `close()`162163Закрывает наблюдатель.164165Этот метод необходимо вызвать, чтобы гарантировать очистку нижележащих ресурсов.166167Устарело с версии 3.12.168169#### `class asyncio.ThreadedChildWatcher`170171Эта реализация запускает новый ожидающий поток для каждого запущенного подпроцесса.172173Она работает надёжно, даже если цикл событий asyncio выполняется не в главном потоке ОС.174175Нет заметных накладных расходов при обработке большого количества дочерних процессов (*O*(1) при каждом завершении дочернего процесса), но запуск отдельного потока на каждый процесс требует дополнительной памяти.176177Этот наблюдатель используется по умолчанию.178179Добавлено в версии 3.8.180181#### `class asyncio.MultiLoopChildWatcher`182183Эта реализация регистрирует обработчик сигнала `SIGCHLD` при создании экземпляра. Это может нарушить работу стороннего кода, который устанавливает собственный обработчик сигнала `SIGCHLD`.184185Наблюдатель не нарушает работу другого кода, запускающего процессы, благодаря явному опросу каждого процесса при получении сигнала `SIGCHLD`.186187После установки наблюдателя нет ограничений на запуск подпроцессов из разных потоков.188189Решение безопасно, но имеет значительные накладные расходы при обработке большого количества процессов (*O*(*n*) при каждом получении `SIGCHLD`).190191Добавлено в версии 3.8.192193Устарело с версии 3.12.194195#### `class asyncio.SafeChildWatcher`196197Эта реализация использует активный цикл событий из главного потока для обработки сигнала `SIGCHLD`. Если в главном потоке нет работающего цикла событий, другой поток не может запустить подпроцесс (возникает [`RuntimeError`](https://python-all.ru/3.13/library/exceptions.html#RuntimeError)).198199Наблюдатель не нарушает работу другого кода, запускающего процессы, благодаря явному опросу каждого процесса при получении сигнала `SIGCHLD`.200201Это решение так же безопасно, как и [`MultiLoopChildWatcher`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.MultiLoopChildWatcher), и имеет ту же сложность *O*(*n*), но для работы требует работающего цикла событий в главном потоке.202203Устарело с версии 3.12.204205#### `class asyncio.FastChildWatcher`206207Эта реализация собирает каждый завершённый процесс, напрямую вызывая `os.waitpid(-1)`, что потенциально нарушает работу другого кода, запускающего процессы и ожидающего их завершения.208209Нет заметных накладных расходов при обработке большого количества дочерних процессов (*O*(1) при каждом завершении дочернего процесса).210211Это решение требует работающего цикла событий в главном потоке, как и [`SafeChildWatcher`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.SafeChildWatcher).212213Устарело с версии 3.12.214215#### `class asyncio.PidfdChildWatcher`216217Данная реализация опрашивает файловые дескрипторы процессов (pidfds) для ожидания завершения дочернего процесса. В некотором смысле `PidfdChildWatcher` – это реализация наблюдателя за дочерними процессами «Златовласка». Она не требует сигналов или потоков, не мешает процессам, запущенным вне цикла событий, и масштабируется линейно от количества подпроцессов, запущенных циклом событий. Основной недостаток в том, что pidfds специфичны для Linux и работают только на современных (5.3+) ядрах.218219Добавлено в версии 3.9.220221## Пользовательские политики222223Для реализации новой политики цикла событий рекомендуется создать подкласс [`DefaultEventLoopPolicy`](https://python-all.ru/3.13/library/asyncio-policy.html#asyncio.DefaultEventLoopPolicy) и переопределить методы, для которых требуется особое поведение, например:224225```python226class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):227228    def get_event_loop(self):229        """Получить цикл событий.230231        Это может быть None или экземпляр EventLoop.232        """233        loop = super().get_event_loop()234        # Сделать что-то с циклом ...235        return loop236237asyncio.set_event_loop_policy(MyEventLoopPolicy())238```239