1 .. currentmodule:: asyncio 2 3 4 .. _asyncio-policies: 5 6 ======== 7 Policies 8 ======== 9 10 An event loop policy is a global per-process object that controls 11 the management of the event loop. Each event loop has a default 12 policy, which can be changed and customized using the policy API. 13 14 A policy defines the notion of *context* and manages a 15 separate event loop per context. The default policy 16 defines *context* to be the current thread. 17 18 By 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 22 Policy objects should implement the APIs defined 23 in the :class:`AbstractEventLoopPolicy` abstract base class. 24 25 26 Getting and Setting the Policy 27 ============================== 28 29 The following functions can be used to get and set the policy 30 for 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 43 Policy Objects 44 ============== 45 46 The 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 89 asyncio ships with the following built-in policies: 90 91 92 .. class:: DefaultEventLoopPolicy 93 94 The default asyncio policy. Uses :class:`SelectorEventLoop` 95 on both Unix and Windows platforms. 96 97 There is no need to install the default policy manually. asyncio 98 is configured to use the default policy automatically. 99 100 101 .. class:: WindowsProactorEventLoopPolicy 102 103 An alternative event loop policy that uses the 104 :class:`ProactorEventLoop` event loop implementation. 105 106 .. availability:: Windows. 107 108 109 Process Watchers 110 ================ 111 112 A process watcher allows customization of how an event loop monitors 113 child processes on Unix. Specifically, the event loop needs to know 114 when a child process has exited. 115 116 In asyncio, child processes are created with 117 :func:`create_subprocess_exec` and :meth:`loop.subprocess_exec` 118 functions. 119 120 asyncio defines the :class:`AbstractChildWatcher` abstract base class, 121 which child watchers should implement, and has two different 122 implementations: :class:`SafeChildWatcher` (configured to be used 123 by default) and :class:`FastChildWatcher`. 124 125 See also the :ref:`Subprocess and Threads <asyncio-subprocess-threads>` 126 section. 127 128 The following two functions can be used to customize the child process watcher 129 implementation used by the asyncio event loop: 130 131 .. function:: get_child_watcher() 132 133 Return the current child watcher for the current policy. 134 135 .. function:: set_child_watcher(watcher) 136 137 Set the current child watcher to *watcher* for the current 138 policy. *watcher* must implement methods defined in the 139 :class:`AbstractChildWatcher` base class. 140 141 .. note:: 142 Third-party event loops implementations might not support 143 custom child watchers. For such event loops, using 144 :func:`set_child_watcher` might be prohibited or have no effect. 145 146 .. class:: AbstractChildWatcher 147 148 .. method:: add_child_handler(pid, callback, \*args) 149 150 Register a new child handler. 151 152 Arrange for ``callback(pid, returncode, *args)`` to be called 153 when a process with PID equal to *pid* terminates. Specifying 154 another callback for the same process replaces the previous 155 handler. 156 157 The *callback* callable must be thread-safe. 158 159 .. method:: remove_child_handler(pid) 160 161 Removes the handler for process with PID equal to *pid*. 162 163 The function returns ``True`` if the handler was successfully 164 removed, ``False`` if there was nothing to remove. 165 166 .. method:: attach_loop(loop) 167 168 Attach the watcher to an event loop. 169 170 If the watcher was previously attached to an event loop, then 171 it is first detached before attaching to the new loop. 172 173 Note: loop may be ``None``. 174 175 .. method:: close() 176 177 Close the watcher. 178 179 This method has to be called to ensure that underlying 180 resources are cleaned-up. 181 182 .. class:: SafeChildWatcher 183 184 This implementation avoids disrupting other code spawning processes 185 by polling every process explicitly on a :py:data:`SIGCHLD` signal. 186 187 This is a safe solution but it has a significant overhead when 188 handling a big number of processes (*O(n)* each time a 189 :py:data:`SIGCHLD` is received). 190 191 asyncio uses this safe implementation by default. 192 193 .. class:: FastChildWatcher 194 195 This implementation reaps every terminated processes by calling 196 ``os.waitpid(-1)`` directly, possibly breaking other code spawning 197 processes and waiting for their termination. 198 199 There is no noticeable overhead when handling a big number of 200 children (*O(1)* each time a child terminates). 201 202 203 Custom Policies 204 =============== 205 206 To implement a new event loop policy, it is recommended to subclass 207 :class:`DefaultEventLoopPolicy` and override the methods for which 208 custom behavior is wanted, e.g.:: 209 210 class MyEventLoopPolicy(asyncio.DefaultEventLoopPolicy): 211 212 def get_event_loop(self): 213 """Get the event loop. 214 215 This may be None or an instance of EventLoop. 216 """ 217 loop = super().get_event_loop() 218 # Do something with loop ... 219 return loop 220 221 asyncio.set_event_loop_policy(MyEventLoopPolicy()) 222