1.. currentmodule:: asyncio
2
3
4.. _asyncio-policies:
5
6========
7Policies
8========
9
10An event loop policy is a global object
11used to get and set the current :ref:`event loop <asyncio-event-loop>`,
12as well as create new event loops.
13The default policy can be :ref:`replaced <asyncio-policy-get-set>` with
14:ref:`built-in alternatives <asyncio-policy-builtin>`
15to use different event loop implementations,
16or substituted by a :ref:`custom policy <asyncio-custom-policies>`
17that can override these behaviors.
18
19The :ref:`policy object <asyncio-policy-objects>`
20gets and sets a separate event loop per *context*.
21This is per-thread by default,
22though custom policies could define *context* differently.
23
24Custom event loop policies can control the behavior of
25:func:`get_event_loop`, :func:`set_event_loop`, and :func:`new_event_loop`.
26
27Policy objects should implement the APIs defined
28in the :class:`AbstractEventLoopPolicy` abstract base class.
29
30
31.. _asyncio-policy-get-set:
32
33Getting and Setting the Policy
34==============================
35
36The following functions can be used to get and set the policy
37for the current process:
38
39.. function:: get_event_loop_policy()
40
41   Return the current process-wide policy.
42
43.. function:: set_event_loop_policy(policy)
44
45   Set the current process-wide policy to *policy*.
46
47   If *policy* is set to ``None``, the default policy is restored.
48
49
50.. _asyncio-policy-objects:
51
52Policy Objects
53==============
54
55The abstract event loop policy base class is defined as follows:
56
57.. class:: AbstractEventLoopPolicy
58
59   An abstract base class for asyncio policies.
60
61   .. method:: get_event_loop()
62
63      Get the event loop for the current context.
64
65      Return an event loop object implementing the
66      :class:`AbstractEventLoop` interface.
67
68      This method should never return ``None``.
69
70      .. versionchanged:: 3.6
71
72   .. method:: set_event_loop(loop)
73
74      Set the event loop for the current context to *loop*.
75
76   .. method:: new_event_loop()
77
78      Create and return a new event loop object.
79
80      This method should never return ``None``.
81
82   .. method:: get_child_watcher()
83
84      Get a child process watcher object.
85
86      Return a watcher object implementing the
87      :class:`AbstractChildWatcher` interface.
88
89      This function is Unix specific.
90
91   .. method:: set_child_watcher(watcher)
92
93      Set the current child process watcher to *watcher*.
94
95      This function is Unix specific.
96
97
98.. _asyncio-policy-builtin:
99
100asyncio ships with the following built-in policies:
101
102
103.. class:: DefaultEventLoopPolicy
104
105   The default asyncio policy.  Uses :class:`SelectorEventLoop`
106   on Unix and :class:`ProactorEventLoop` on Windows.
107
108   There is no need to install the default policy manually. asyncio
109   is configured to use the default policy automatically.
110
111   .. versionchanged:: 3.8
112
113      On Windows, :class:`ProactorEventLoop` is now used by default.
114
115   .. note::
116      In Python versions 3.10.9, 3.11.1 and 3.12 the :meth:`get_event_loop`
117      method of the default asyncio policy emits a :exc:`DeprecationWarning`
118      if there is no running event loop and no current loop is set.
119      In some future Python release this will become an error.
120
121
122.. class:: WindowsSelectorEventLoopPolicy
123
124   An alternative event loop policy that uses the
125   :class:`SelectorEventLoop` event loop implementation.
126
127   .. availability:: Windows.
128
129
130.. class:: WindowsProactorEventLoopPolicy
131
132   An alternative event loop policy that uses the
133   :class:`ProactorEventLoop` event loop implementation.
134
135   .. availability:: Windows.
136
137
138.. _asyncio-watchers:
139
140Process Watchers
141================
142
143A process watcher allows customization of how an event loop monitors
144child processes on Unix. Specifically, the event loop needs to know
145when a child process has exited.
146
147In asyncio, child processes are created with
148:func:`create_subprocess_exec` and :meth:`loop.subprocess_exec`
149functions.
150
151asyncio defines the :class:`AbstractChildWatcher` abstract base class, which child
152watchers should implement, and has four different implementations:
153:class:`ThreadedChildWatcher` (configured to be used by default),
154:class:`MultiLoopChildWatcher`, :class:`SafeChildWatcher`, and
155:class:`FastChildWatcher`.
156
157See also the :ref:`Subprocess and Threads <asyncio-subprocess-threads>`
158section.
159
160The following two functions can be used to customize the child process watcher
161implementation used by the asyncio event loop:
162
163.. function:: get_child_watcher()
164
165   Return the current child watcher for the current policy.
166
167.. function:: set_child_watcher(watcher)
168
169   Set the current child watcher to *watcher* for the current
170   policy.  *watcher* must implement methods defined in the
171   :class:`AbstractChildWatcher` base class.
172
173.. note::
174   Third-party event loops implementations might not support
175   custom child watchers.  For such event loops, using
176   :func:`set_child_watcher` might be prohibited or have no effect.
177
178.. class:: AbstractChildWatcher
179
180   .. method:: add_child_handler(pid, callback, *args)
181
182      Register a new child handler.
183
184      Arrange for ``callback(pid, returncode, *args)`` to be called
185      when a process with PID equal to *pid* terminates.  Specifying
186      another callback for the same process replaces the previous
187      handler.
188
189      The *callback* callable must be thread-safe.
190
191   .. method:: remove_child_handler(pid)
192
193      Removes the handler for process with PID equal to *pid*.
194
195      The function returns ``True`` if the handler was successfully
196      removed, ``False`` if there was nothing to remove.
197
198   .. method:: attach_loop(loop)
199
200      Attach the watcher to an event loop.
201
202      If the watcher was previously attached to an event loop, then
203      it is first detached before attaching to the new loop.
204
205      Note: loop may be ``None``.
206
207   .. method:: is_active()
208
209      Return ``True`` if the watcher is ready to use.
210
211      Spawning a subprocess with *inactive* current child watcher raises
212      :exc:`RuntimeError`.
213
214      .. versionadded:: 3.8
215
216   .. method:: close()
217
218      Close the watcher.
219
220      This method has to be called to ensure that underlying
221      resources are cleaned-up.
222
223.. class:: ThreadedChildWatcher
224
225   This implementation starts a new waiting thread for every subprocess spawn.
226
227   It works reliably even when the asyncio event loop is run in a non-main OS thread.
228
229   There is no noticeable overhead when handling a big number of children (*O(1)* each
230   time a child terminates), but starting a thread per process requires extra memory.
231
232   This watcher is used by default.
233
234   .. versionadded:: 3.8
235
236.. class:: MultiLoopChildWatcher
237
238   This implementation registers a :py:data:`SIGCHLD` signal handler on
239   instantiation. That can break third-party code that installs a custom handler for
240   :py:data:`SIGCHLD` signal.
241
242   The watcher avoids disrupting other code spawning processes
243   by polling every process explicitly on a :py:data:`SIGCHLD` signal.
244
245   There is no limitation for running subprocesses from different threads once the
246   watcher is installed.
247
248   The solution is safe but it has a significant overhead when
249   handling a big number of processes (*O(n)* each time a
250   :py:data:`SIGCHLD` is received).
251
252   .. versionadded:: 3.8
253
254.. class:: SafeChildWatcher
255
256   This implementation uses active event loop from the main thread to handle
257   :py:data:`SIGCHLD` signal. If the main thread has no running event loop another
258   thread cannot spawn a subprocess (:exc:`RuntimeError` is raised).
259
260   The watcher avoids disrupting other code spawning processes
261   by polling every process explicitly on a :py:data:`SIGCHLD` signal.
262
263   This solution is as safe as :class:`MultiLoopChildWatcher` and has the same *O(N)*
264   complexity but requires a running event loop in the main thread to work.
265
266.. class:: FastChildWatcher
267
268   This implementation reaps every terminated processes by calling
269   ``os.waitpid(-1)`` directly, possibly breaking other code spawning
270   processes and waiting for their termination.
271
272   There is no noticeable overhead when handling a big number of
273   children (*O(1)* each time a child terminates).
274
275   This solution requires a running event loop in the main thread to work, as
276   :class:`SafeChildWatcher`.
277
278.. class:: PidfdChildWatcher
279
280   This implementation polls process file descriptors (pidfds) to await child
281   process termination. In some respects, :class:`PidfdChildWatcher` is a
282   "Goldilocks" child watcher implementation. It doesn't require signals or
283   threads, doesn't interfere with any processes launched outside the event
284   loop, and scales linearly with the number of subprocesses launched by the
285   event loop. The main disadvantage is that pidfds are specific to Linux, and
286   only work on recent (5.3+) kernels.
287
288   .. versionadded:: 3.9
289
290
291.. _asyncio-custom-policies:
292
293Custom Policies
294===============
295
296To implement a new event loop policy, it is recommended to subclass
297:class:`DefaultEventLoopPolicy` and override the methods for which
298custom behavior is wanted, e.g.::
299
300    class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy):
301
302        def get_event_loop(self):
303            """Get the event loop.
304
305            This may be None or an instance of EventLoop.
306            """
307            loop = super().get_event_loop()
308            # Do something with loop ...
309            return loop
310
311    asyncio.set_event_loop_policy(MyEventLoopPolicy())
312