@@ -79,25 +79,6 @@ The abstract event loop policy base class is defined as follows:
79
79
80
80
This method should never return ``None ``.
81
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
- .. deprecated :: 3.12
92
-
93
- .. method :: set_child_watcher(watcher)
94
-
95
- Set the current child process watcher to *watcher *.
96
-
97
- This function is Unix specific.
98
-
99
- .. deprecated :: 3.12
100
-
101
82
102
83
.. _asyncio-policy-builtin :
103
84
@@ -139,172 +120,6 @@ asyncio ships with the following built-in policies:
139
120
.. availability :: Windows.
140
121
141
122
142
- .. _asyncio-watchers :
143
-
144
- Process Watchers
145
- ================
146
-
147
- A process watcher allows customization of how an event loop monitors
148
- child processes on Unix. Specifically, the event loop needs to know
149
- when a child process has exited.
150
-
151
- In asyncio, child processes are created with
152
- :func: `create_subprocess_exec ` and :meth: `loop.subprocess_exec `
153
- functions.
154
-
155
- asyncio defines the :class: `AbstractChildWatcher ` abstract base class, which child
156
- watchers should implement, and has four different implementations:
157
- :class: `ThreadedChildWatcher ` (configured to be used by default),
158
- :class: `MultiLoopChildWatcher `, :class: `SafeChildWatcher `, and
159
- :class: `FastChildWatcher `.
160
-
161
- See also the :ref: `Subprocess and Threads <asyncio-subprocess-threads >`
162
- section.
163
-
164
- The following two functions can be used to customize the child process watcher
165
- implementation used by the asyncio event loop:
166
-
167
- .. function :: get_child_watcher()
168
-
169
- Return the current child watcher for the current policy.
170
-
171
- .. deprecated :: 3.12
172
-
173
- .. function :: set_child_watcher(watcher)
174
-
175
- Set the current child watcher to *watcher * for the current
176
- policy. *watcher * must implement methods defined in the
177
- :class: `AbstractChildWatcher ` base class.
178
-
179
- .. deprecated :: 3.12
180
-
181
- .. note ::
182
- Third-party event loops implementations might not support
183
- custom child watchers. For such event loops, using
184
- :func: `set_child_watcher ` might be prohibited or have no effect.
185
-
186
- .. class :: AbstractChildWatcher
187
-
188
- .. method :: add_child_handler(pid, callback, *args)
189
-
190
- Register a new child handler.
191
-
192
- Arrange for ``callback(pid, returncode, *args) `` to be called
193
- when a process with PID equal to *pid * terminates. Specifying
194
- another callback for the same process replaces the previous
195
- handler.
196
-
197
- The *callback * callable must be thread-safe.
198
-
199
- .. method :: remove_child_handler(pid)
200
-
201
- Removes the handler for process with PID equal to *pid *.
202
-
203
- The function returns ``True `` if the handler was successfully
204
- removed, ``False `` if there was nothing to remove.
205
-
206
- .. method :: attach_loop(loop)
207
-
208
- Attach the watcher to an event loop.
209
-
210
- If the watcher was previously attached to an event loop, then
211
- it is first detached before attaching to the new loop.
212
-
213
- Note: loop may be ``None ``.
214
-
215
- .. method :: is_active()
216
-
217
- Return ``True `` if the watcher is ready to use.
218
-
219
- Spawning a subprocess with *inactive * current child watcher raises
220
- :exc: `RuntimeError `.
221
-
222
- .. versionadded :: 3.8
223
-
224
- .. method :: close()
225
-
226
- Close the watcher.
227
-
228
- This method has to be called to ensure that underlying
229
- resources are cleaned-up.
230
-
231
- .. deprecated :: 3.12
232
-
233
-
234
- .. class :: ThreadedChildWatcher
235
-
236
- This implementation starts a new waiting thread for every subprocess spawn.
237
-
238
- It works reliably even when the asyncio event loop is run in a non-main OS thread.
239
-
240
- There is no noticeable overhead when handling a big number of children (*O *\ (1) each
241
- time a child terminates), but starting a thread per process requires extra memory.
242
-
243
- This watcher is used by default.
244
-
245
- .. versionadded :: 3.8
246
-
247
- .. class :: MultiLoopChildWatcher
248
-
249
- This implementation registers a :py:data: `SIGCHLD ` signal handler on
250
- instantiation. That can break third-party code that installs a custom handler for
251
- :py:data: `SIGCHLD ` signal.
252
-
253
- The watcher avoids disrupting other code spawning processes
254
- by polling every process explicitly on a :py:data: `SIGCHLD ` signal.
255
-
256
- There is no limitation for running subprocesses from different threads once the
257
- watcher is installed.
258
-
259
- The solution is safe but it has a significant overhead when
260
- handling a big number of processes (*O *\ (*n *) each time a
261
- :py:data: `SIGCHLD ` is received).
262
-
263
- .. versionadded :: 3.8
264
-
265
- .. deprecated :: 3.12
266
-
267
- .. class :: SafeChildWatcher
268
-
269
- This implementation uses active event loop from the main thread to handle
270
- :py:data: `SIGCHLD ` signal. If the main thread has no running event loop another
271
- thread cannot spawn a subprocess (:exc: `RuntimeError ` is raised).
272
-
273
- The watcher avoids disrupting other code spawning processes
274
- by polling every process explicitly on a :py:data: `SIGCHLD ` signal.
275
-
276
- This solution is as safe as :class: `MultiLoopChildWatcher ` and has the same *O *\ (*n *)
277
- complexity but requires a running event loop in the main thread to work.
278
-
279
- .. deprecated :: 3.12
280
-
281
- .. class :: FastChildWatcher
282
-
283
- This implementation reaps every terminated processes by calling
284
- ``os.waitpid(-1) `` directly, possibly breaking other code spawning
285
- processes and waiting for their termination.
286
-
287
- There is no noticeable overhead when handling a big number of
288
- children (*O *\ (1) each time a child terminates).
289
-
290
- This solution requires a running event loop in the main thread to work, as
291
- :class: `SafeChildWatcher `.
292
-
293
- .. deprecated :: 3.12
294
-
295
- .. class :: PidfdChildWatcher
296
-
297
- This implementation polls process file descriptors (pidfds) to await child
298
- process termination. In some respects, :class: `PidfdChildWatcher ` is a
299
- "Goldilocks" child watcher implementation. It doesn't require signals or
300
- threads, doesn't interfere with any processes launched outside the event
301
- loop, and scales linearly with the number of subprocesses launched by the
302
- event loop. The main disadvantage is that pidfds are specific to Linux, and
303
- only work on recent (5.3+) kernels.
304
-
305
- .. versionadded :: 3.9
306
-
307
-
308
123
.. _asyncio-custom-policies :
309
124
310
125
Custom Policies
0 commit comments