17db96d56Sopenharmony_ci.. currentmodule:: asyncio
27db96d56Sopenharmony_ci
37db96d56Sopenharmony_ci
47db96d56Sopenharmony_ci.. _asyncio-policies:
57db96d56Sopenharmony_ci
67db96d56Sopenharmony_ci========
77db96d56Sopenharmony_ciPolicies
87db96d56Sopenharmony_ci========
97db96d56Sopenharmony_ci
107db96d56Sopenharmony_ciAn event loop policy is a global object
117db96d56Sopenharmony_ciused to get and set the current :ref:`event loop <asyncio-event-loop>`,
127db96d56Sopenharmony_cias well as create new event loops.
137db96d56Sopenharmony_ciThe default policy can be :ref:`replaced <asyncio-policy-get-set>` with
147db96d56Sopenharmony_ci:ref:`built-in alternatives <asyncio-policy-builtin>`
157db96d56Sopenharmony_cito use different event loop implementations,
167db96d56Sopenharmony_cior substituted by a :ref:`custom policy <asyncio-custom-policies>`
177db96d56Sopenharmony_cithat can override these behaviors.
187db96d56Sopenharmony_ci
197db96d56Sopenharmony_ciThe :ref:`policy object <asyncio-policy-objects>`
207db96d56Sopenharmony_cigets and sets a separate event loop per *context*.
217db96d56Sopenharmony_ciThis is per-thread by default,
227db96d56Sopenharmony_cithough custom policies could define *context* differently.
237db96d56Sopenharmony_ci
247db96d56Sopenharmony_ciCustom event loop policies can control the behavior of
257db96d56Sopenharmony_ci:func:`get_event_loop`, :func:`set_event_loop`, and :func:`new_event_loop`.
267db96d56Sopenharmony_ci
277db96d56Sopenharmony_ciPolicy objects should implement the APIs defined
287db96d56Sopenharmony_ciin the :class:`AbstractEventLoopPolicy` abstract base class.
297db96d56Sopenharmony_ci
307db96d56Sopenharmony_ci
317db96d56Sopenharmony_ci.. _asyncio-policy-get-set:
327db96d56Sopenharmony_ci
337db96d56Sopenharmony_ciGetting and Setting the Policy
347db96d56Sopenharmony_ci==============================
357db96d56Sopenharmony_ci
367db96d56Sopenharmony_ciThe following functions can be used to get and set the policy
377db96d56Sopenharmony_cifor the current process:
387db96d56Sopenharmony_ci
397db96d56Sopenharmony_ci.. function:: get_event_loop_policy()
407db96d56Sopenharmony_ci
417db96d56Sopenharmony_ci   Return the current process-wide policy.
427db96d56Sopenharmony_ci
437db96d56Sopenharmony_ci.. function:: set_event_loop_policy(policy)
447db96d56Sopenharmony_ci
457db96d56Sopenharmony_ci   Set the current process-wide policy to *policy*.
467db96d56Sopenharmony_ci
477db96d56Sopenharmony_ci   If *policy* is set to ``None``, the default policy is restored.
487db96d56Sopenharmony_ci
497db96d56Sopenharmony_ci
507db96d56Sopenharmony_ci.. _asyncio-policy-objects:
517db96d56Sopenharmony_ci
527db96d56Sopenharmony_ciPolicy Objects
537db96d56Sopenharmony_ci==============
547db96d56Sopenharmony_ci
557db96d56Sopenharmony_ciThe abstract event loop policy base class is defined as follows:
567db96d56Sopenharmony_ci
577db96d56Sopenharmony_ci.. class:: AbstractEventLoopPolicy
587db96d56Sopenharmony_ci
597db96d56Sopenharmony_ci   An abstract base class for asyncio policies.
607db96d56Sopenharmony_ci
617db96d56Sopenharmony_ci   .. method:: get_event_loop()
627db96d56Sopenharmony_ci
637db96d56Sopenharmony_ci      Get the event loop for the current context.
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ci      Return an event loop object implementing the
667db96d56Sopenharmony_ci      :class:`AbstractEventLoop` interface.
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ci      This method should never return ``None``.
697db96d56Sopenharmony_ci
707db96d56Sopenharmony_ci      .. versionchanged:: 3.6
717db96d56Sopenharmony_ci
727db96d56Sopenharmony_ci   .. method:: set_event_loop(loop)
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_ci      Set the event loop for the current context to *loop*.
757db96d56Sopenharmony_ci
767db96d56Sopenharmony_ci   .. method:: new_event_loop()
777db96d56Sopenharmony_ci
787db96d56Sopenharmony_ci      Create and return a new event loop object.
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ci      This method should never return ``None``.
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ci   .. method:: get_child_watcher()
837db96d56Sopenharmony_ci
847db96d56Sopenharmony_ci      Get a child process watcher object.
857db96d56Sopenharmony_ci
867db96d56Sopenharmony_ci      Return a watcher object implementing the
877db96d56Sopenharmony_ci      :class:`AbstractChildWatcher` interface.
887db96d56Sopenharmony_ci
897db96d56Sopenharmony_ci      This function is Unix specific.
907db96d56Sopenharmony_ci
917db96d56Sopenharmony_ci   .. method:: set_child_watcher(watcher)
927db96d56Sopenharmony_ci
937db96d56Sopenharmony_ci      Set the current child process watcher to *watcher*.
947db96d56Sopenharmony_ci
957db96d56Sopenharmony_ci      This function is Unix specific.
967db96d56Sopenharmony_ci
977db96d56Sopenharmony_ci
987db96d56Sopenharmony_ci.. _asyncio-policy-builtin:
997db96d56Sopenharmony_ci
1007db96d56Sopenharmony_ciasyncio ships with the following built-in policies:
1017db96d56Sopenharmony_ci
1027db96d56Sopenharmony_ci
1037db96d56Sopenharmony_ci.. class:: DefaultEventLoopPolicy
1047db96d56Sopenharmony_ci
1057db96d56Sopenharmony_ci   The default asyncio policy.  Uses :class:`SelectorEventLoop`
1067db96d56Sopenharmony_ci   on Unix and :class:`ProactorEventLoop` on Windows.
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_ci   There is no need to install the default policy manually. asyncio
1097db96d56Sopenharmony_ci   is configured to use the default policy automatically.
1107db96d56Sopenharmony_ci
1117db96d56Sopenharmony_ci   .. versionchanged:: 3.8
1127db96d56Sopenharmony_ci
1137db96d56Sopenharmony_ci      On Windows, :class:`ProactorEventLoop` is now used by default.
1147db96d56Sopenharmony_ci
1157db96d56Sopenharmony_ci   .. note::
1167db96d56Sopenharmony_ci      In Python versions 3.10.9, 3.11.1 and 3.12 the :meth:`get_event_loop`
1177db96d56Sopenharmony_ci      method of the default asyncio policy emits a :exc:`DeprecationWarning`
1187db96d56Sopenharmony_ci      if there is no running event loop and no current loop is set.
1197db96d56Sopenharmony_ci      In some future Python release this will become an error.
1207db96d56Sopenharmony_ci
1217db96d56Sopenharmony_ci
1227db96d56Sopenharmony_ci.. class:: WindowsSelectorEventLoopPolicy
1237db96d56Sopenharmony_ci
1247db96d56Sopenharmony_ci   An alternative event loop policy that uses the
1257db96d56Sopenharmony_ci   :class:`SelectorEventLoop` event loop implementation.
1267db96d56Sopenharmony_ci
1277db96d56Sopenharmony_ci   .. availability:: Windows.
1287db96d56Sopenharmony_ci
1297db96d56Sopenharmony_ci
1307db96d56Sopenharmony_ci.. class:: WindowsProactorEventLoopPolicy
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ci   An alternative event loop policy that uses the
1337db96d56Sopenharmony_ci   :class:`ProactorEventLoop` event loop implementation.
1347db96d56Sopenharmony_ci
1357db96d56Sopenharmony_ci   .. availability:: Windows.
1367db96d56Sopenharmony_ci
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci.. _asyncio-watchers:
1397db96d56Sopenharmony_ci
1407db96d56Sopenharmony_ciProcess Watchers
1417db96d56Sopenharmony_ci================
1427db96d56Sopenharmony_ci
1437db96d56Sopenharmony_ciA process watcher allows customization of how an event loop monitors
1447db96d56Sopenharmony_cichild processes on Unix. Specifically, the event loop needs to know
1457db96d56Sopenharmony_ciwhen a child process has exited.
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ciIn asyncio, child processes are created with
1487db96d56Sopenharmony_ci:func:`create_subprocess_exec` and :meth:`loop.subprocess_exec`
1497db96d56Sopenharmony_cifunctions.
1507db96d56Sopenharmony_ci
1517db96d56Sopenharmony_ciasyncio defines the :class:`AbstractChildWatcher` abstract base class, which child
1527db96d56Sopenharmony_ciwatchers should implement, and has four different implementations:
1537db96d56Sopenharmony_ci:class:`ThreadedChildWatcher` (configured to be used by default),
1547db96d56Sopenharmony_ci:class:`MultiLoopChildWatcher`, :class:`SafeChildWatcher`, and
1557db96d56Sopenharmony_ci:class:`FastChildWatcher`.
1567db96d56Sopenharmony_ci
1577db96d56Sopenharmony_ciSee also the :ref:`Subprocess and Threads <asyncio-subprocess-threads>`
1587db96d56Sopenharmony_cisection.
1597db96d56Sopenharmony_ci
1607db96d56Sopenharmony_ciThe following two functions can be used to customize the child process watcher
1617db96d56Sopenharmony_ciimplementation used by the asyncio event loop:
1627db96d56Sopenharmony_ci
1637db96d56Sopenharmony_ci.. function:: get_child_watcher()
1647db96d56Sopenharmony_ci
1657db96d56Sopenharmony_ci   Return the current child watcher for the current policy.
1667db96d56Sopenharmony_ci
1677db96d56Sopenharmony_ci.. function:: set_child_watcher(watcher)
1687db96d56Sopenharmony_ci
1697db96d56Sopenharmony_ci   Set the current child watcher to *watcher* for the current
1707db96d56Sopenharmony_ci   policy.  *watcher* must implement methods defined in the
1717db96d56Sopenharmony_ci   :class:`AbstractChildWatcher` base class.
1727db96d56Sopenharmony_ci
1737db96d56Sopenharmony_ci.. note::
1747db96d56Sopenharmony_ci   Third-party event loops implementations might not support
1757db96d56Sopenharmony_ci   custom child watchers.  For such event loops, using
1767db96d56Sopenharmony_ci   :func:`set_child_watcher` might be prohibited or have no effect.
1777db96d56Sopenharmony_ci
1787db96d56Sopenharmony_ci.. class:: AbstractChildWatcher
1797db96d56Sopenharmony_ci
1807db96d56Sopenharmony_ci   .. method:: add_child_handler(pid, callback, *args)
1817db96d56Sopenharmony_ci
1827db96d56Sopenharmony_ci      Register a new child handler.
1837db96d56Sopenharmony_ci
1847db96d56Sopenharmony_ci      Arrange for ``callback(pid, returncode, *args)`` to be called
1857db96d56Sopenharmony_ci      when a process with PID equal to *pid* terminates.  Specifying
1867db96d56Sopenharmony_ci      another callback for the same process replaces the previous
1877db96d56Sopenharmony_ci      handler.
1887db96d56Sopenharmony_ci
1897db96d56Sopenharmony_ci      The *callback* callable must be thread-safe.
1907db96d56Sopenharmony_ci
1917db96d56Sopenharmony_ci   .. method:: remove_child_handler(pid)
1927db96d56Sopenharmony_ci
1937db96d56Sopenharmony_ci      Removes the handler for process with PID equal to *pid*.
1947db96d56Sopenharmony_ci
1957db96d56Sopenharmony_ci      The function returns ``True`` if the handler was successfully
1967db96d56Sopenharmony_ci      removed, ``False`` if there was nothing to remove.
1977db96d56Sopenharmony_ci
1987db96d56Sopenharmony_ci   .. method:: attach_loop(loop)
1997db96d56Sopenharmony_ci
2007db96d56Sopenharmony_ci      Attach the watcher to an event loop.
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_ci      If the watcher was previously attached to an event loop, then
2037db96d56Sopenharmony_ci      it is first detached before attaching to the new loop.
2047db96d56Sopenharmony_ci
2057db96d56Sopenharmony_ci      Note: loop may be ``None``.
2067db96d56Sopenharmony_ci
2077db96d56Sopenharmony_ci   .. method:: is_active()
2087db96d56Sopenharmony_ci
2097db96d56Sopenharmony_ci      Return ``True`` if the watcher is ready to use.
2107db96d56Sopenharmony_ci
2117db96d56Sopenharmony_ci      Spawning a subprocess with *inactive* current child watcher raises
2127db96d56Sopenharmony_ci      :exc:`RuntimeError`.
2137db96d56Sopenharmony_ci
2147db96d56Sopenharmony_ci      .. versionadded:: 3.8
2157db96d56Sopenharmony_ci
2167db96d56Sopenharmony_ci   .. method:: close()
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci      Close the watcher.
2197db96d56Sopenharmony_ci
2207db96d56Sopenharmony_ci      This method has to be called to ensure that underlying
2217db96d56Sopenharmony_ci      resources are cleaned-up.
2227db96d56Sopenharmony_ci
2237db96d56Sopenharmony_ci.. class:: ThreadedChildWatcher
2247db96d56Sopenharmony_ci
2257db96d56Sopenharmony_ci   This implementation starts a new waiting thread for every subprocess spawn.
2267db96d56Sopenharmony_ci
2277db96d56Sopenharmony_ci   It works reliably even when the asyncio event loop is run in a non-main OS thread.
2287db96d56Sopenharmony_ci
2297db96d56Sopenharmony_ci   There is no noticeable overhead when handling a big number of children (*O(1)* each
2307db96d56Sopenharmony_ci   time a child terminates), but starting a thread per process requires extra memory.
2317db96d56Sopenharmony_ci
2327db96d56Sopenharmony_ci   This watcher is used by default.
2337db96d56Sopenharmony_ci
2347db96d56Sopenharmony_ci   .. versionadded:: 3.8
2357db96d56Sopenharmony_ci
2367db96d56Sopenharmony_ci.. class:: MultiLoopChildWatcher
2377db96d56Sopenharmony_ci
2387db96d56Sopenharmony_ci   This implementation registers a :py:data:`SIGCHLD` signal handler on
2397db96d56Sopenharmony_ci   instantiation. That can break third-party code that installs a custom handler for
2407db96d56Sopenharmony_ci   :py:data:`SIGCHLD` signal.
2417db96d56Sopenharmony_ci
2427db96d56Sopenharmony_ci   The watcher avoids disrupting other code spawning processes
2437db96d56Sopenharmony_ci   by polling every process explicitly on a :py:data:`SIGCHLD` signal.
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ci   There is no limitation for running subprocesses from different threads once the
2467db96d56Sopenharmony_ci   watcher is installed.
2477db96d56Sopenharmony_ci
2487db96d56Sopenharmony_ci   The solution is safe but it has a significant overhead when
2497db96d56Sopenharmony_ci   handling a big number of processes (*O(n)* each time a
2507db96d56Sopenharmony_ci   :py:data:`SIGCHLD` is received).
2517db96d56Sopenharmony_ci
2527db96d56Sopenharmony_ci   .. versionadded:: 3.8
2537db96d56Sopenharmony_ci
2547db96d56Sopenharmony_ci.. class:: SafeChildWatcher
2557db96d56Sopenharmony_ci
2567db96d56Sopenharmony_ci   This implementation uses active event loop from the main thread to handle
2577db96d56Sopenharmony_ci   :py:data:`SIGCHLD` signal. If the main thread has no running event loop another
2587db96d56Sopenharmony_ci   thread cannot spawn a subprocess (:exc:`RuntimeError` is raised).
2597db96d56Sopenharmony_ci
2607db96d56Sopenharmony_ci   The watcher avoids disrupting other code spawning processes
2617db96d56Sopenharmony_ci   by polling every process explicitly on a :py:data:`SIGCHLD` signal.
2627db96d56Sopenharmony_ci
2637db96d56Sopenharmony_ci   This solution is as safe as :class:`MultiLoopChildWatcher` and has the same *O(N)*
2647db96d56Sopenharmony_ci   complexity but requires a running event loop in the main thread to work.
2657db96d56Sopenharmony_ci
2667db96d56Sopenharmony_ci.. class:: FastChildWatcher
2677db96d56Sopenharmony_ci
2687db96d56Sopenharmony_ci   This implementation reaps every terminated processes by calling
2697db96d56Sopenharmony_ci   ``os.waitpid(-1)`` directly, possibly breaking other code spawning
2707db96d56Sopenharmony_ci   processes and waiting for their termination.
2717db96d56Sopenharmony_ci
2727db96d56Sopenharmony_ci   There is no noticeable overhead when handling a big number of
2737db96d56Sopenharmony_ci   children (*O(1)* each time a child terminates).
2747db96d56Sopenharmony_ci
2757db96d56Sopenharmony_ci   This solution requires a running event loop in the main thread to work, as
2767db96d56Sopenharmony_ci   :class:`SafeChildWatcher`.
2777db96d56Sopenharmony_ci
2787db96d56Sopenharmony_ci.. class:: PidfdChildWatcher
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ci   This implementation polls process file descriptors (pidfds) to await child
2817db96d56Sopenharmony_ci   process termination. In some respects, :class:`PidfdChildWatcher` is a
2827db96d56Sopenharmony_ci   "Goldilocks" child watcher implementation. It doesn't require signals or
2837db96d56Sopenharmony_ci   threads, doesn't interfere with any processes launched outside the event
2847db96d56Sopenharmony_ci   loop, and scales linearly with the number of subprocesses launched by the
2857db96d56Sopenharmony_ci   event loop. The main disadvantage is that pidfds are specific to Linux, and
2867db96d56Sopenharmony_ci   only work on recent (5.3+) kernels.
2877db96d56Sopenharmony_ci
2887db96d56Sopenharmony_ci   .. versionadded:: 3.9
2897db96d56Sopenharmony_ci
2907db96d56Sopenharmony_ci
2917db96d56Sopenharmony_ci.. _asyncio-custom-policies:
2927db96d56Sopenharmony_ci
2937db96d56Sopenharmony_ciCustom Policies
2947db96d56Sopenharmony_ci===============
2957db96d56Sopenharmony_ci
2967db96d56Sopenharmony_ciTo implement a new event loop policy, it is recommended to subclass
2977db96d56Sopenharmony_ci:class:`DefaultEventLoopPolicy` and override the methods for which
2987db96d56Sopenharmony_cicustom behavior is wanted, e.g.::
2997db96d56Sopenharmony_ci
3007db96d56Sopenharmony_ci    class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
3017db96d56Sopenharmony_ci
3027db96d56Sopenharmony_ci        def get_event_loop(self):
3037db96d56Sopenharmony_ci            """Get the event loop.
3047db96d56Sopenharmony_ci
3057db96d56Sopenharmony_ci            This may be None or an instance of EventLoop.
3067db96d56Sopenharmony_ci            """
3077db96d56Sopenharmony_ci            loop = super().get_event_loop()
3087db96d56Sopenharmony_ci            # Do something with loop ...
3097db96d56Sopenharmony_ci            return loop
3107db96d56Sopenharmony_ci
3117db96d56Sopenharmony_ci    asyncio.set_event_loop_policy(MyEventLoopPolicy())
312