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