Issue #21680: Document asyncio event loops

This commit is contained in:
Victor Stinner 2014-07-08 23:42:38 +02:00
parent 530ef2f069
commit aea82293be
4 changed files with 193 additions and 86 deletions

View File

@ -2,8 +2,8 @@
.. _asyncio-event-loop:
Event loops
===========
Base Event Loop
===============
The event loop is the central execution device provided by :mod:`asyncio`.
It provides multiple facilities, amongst which:
@ -18,78 +18,9 @@ It provides multiple facilities, amongst which:
* Delegating costly function calls to a pool of threads.
Event loop policies and the default policy
------------------------------------------
.. class:: BaseEventLoop
Event loop management is abstracted with a *policy* pattern, to provide maximal
flexibility for custom platforms and frameworks. Throughout the execution of a
process, a single global policy object manages the event loops available to the
process based on the calling context. A policy is an object implementing the
:class:`AbstractEventLoopPolicy` interface.
For most users of :mod:`asyncio`, policies never have to be dealt with
explicitly, since the default global policy is sufficient.
The default policy defines context as the current thread, and manages an event
loop per thread that interacts with :mod:`asyncio`. The module-level functions
:func:`get_event_loop` and :func:`set_event_loop` provide convenient access to
event loops managed by the default policy.
Event loop functions
--------------------
The following functions are convenient shortcuts to accessing the methods of the
global policy. Note that this provides access to the default policy, unless an
alternative policy was set by calling :func:`set_event_loop_policy` earlier in
the execution of the process.
.. function:: get_event_loop()
Equivalent to calling ``get_event_loop_policy().get_event_loop()``.
.. function:: set_event_loop(loop)
Equivalent to calling ``get_event_loop_policy().set_event_loop(loop)``.
.. function:: new_event_loop()
Equivalent to calling ``get_event_loop_policy().new_event_loop()``.
Event loop policy interface
---------------------------
An event loop policy must implement the following interface:
.. class:: AbstractEventLoopPolicy
.. method:: get_event_loop()
Get the event loop for the current context. Returns an event loop object
implementing the :class:`BaseEventLoop` interface, or raises an exception in case
no event loop has been set for the current context and the current policy
does not specify to create one. It should never return ``None``.
.. method:: set_event_loop(loop)
Set the event loop for the current context to *loop*.
.. method:: new_event_loop()
Create and return a new event loop object according to this policy's rules.
If there's need to set this loop as the event loop for the current context,
:meth:`set_event_loop` must be called explicitly.
Access to the global loop policy
--------------------------------
.. function:: get_event_loop_policy()
Get the current event loop policy.
.. function:: set_event_loop_policy(policy)
Set the current event loop policy. If *policy* is ``None``, the default
policy is restored.
Base class of event loops.
Run an event loop
-----------------
@ -375,7 +306,6 @@ Creating listening connections
Availability: UNIX.
Watch file descriptors
----------------------
@ -624,7 +554,6 @@ Debug mode
The :ref:`debug mode of asyncio <asyncio-debug-mode>`.
Server
------
@ -652,7 +581,8 @@ Handle
.. method:: cancel()
Cancel the call.
Cancel the call.
.. _asyncio-hello-world-callback:

View File

@ -0,0 +1,176 @@
.. currentmodule:: asyncio
Event loops
===========
Event loop functions
--------------------
The following functions are convenient shortcuts to accessing the methods of the
global policy. Note that this provides access to the default policy, unless an
alternative policy was set by calling :func:`set_event_loop_policy` earlier in
the execution of the process.
.. function:: get_event_loop()
Equivalent to calling ``get_event_loop_policy().get_event_loop()``.
.. function:: set_event_loop(loop)
Equivalent to calling ``get_event_loop_policy().set_event_loop(loop)``.
.. function:: new_event_loop()
Equivalent to calling ``get_event_loop_policy().new_event_loop()``.
Available event loops
---------------------
asyncio currently provides two implementations of event loops:
:class:`SelectorEventLoop` and :class:`ProactorEventLoop`.
.. class:: SelectorEventLoop
Event loop based on the :mod:`selectors` module. Subclass of
:class:`BaseEventLoop`.
Use the most efficient selector available on the platform.
.. class:: ProactorEventLoop
Proactor event loop for Windows using "I/O Completion Ports" aka IOCP.
Subclass of :class:`BaseEventLoop`.
Availability: Windows.
.. seealso::
`MSDN documentation on I/O Completion Ports
<http://msdn.microsoft.com/en-us/library/windows/desktop/aa365198%28v=vs.85%29.aspx>`_.
Example to use a :class:`ProactorEventLoop` on Windows::
import asyncio, os
if os.name == 'nt':
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
Platform support
----------------
The :mod:`asyncio` module has been designed to be portable, but each platform
still has subtle differences and may not support all :mod:`asyncio` features.
Windows
^^^^^^^
Common limits of Windows event loops:
- :meth:`~BaseEventLoop.create_unix_server` and
:meth:`~BaseEventLoop.create_unix_server` are not supported: specific to UNIX
- :meth:`~BaseEventLoop.add_signal_handler` and
:meth:`~BaseEventLoop.remove_signal_handler` are not supported
- Pipes are not supported: :meth:`~BaseEventLoop.connect_read_pipe` and
:meth:`~BaseEventLoop.connect_write_pipe`
- :meth:`EventLoopPolicy.set_child_watcher` is not supported
:class:`SelectorEventLoop` specific limits:
- :class:`~selectors.SelectSelector` is used but it only supports sockets,
see the `MSDN documentation of select
<http://msdn.microsoft.com/en-us/library/windows/desktop/ms740141%28v=vs.85%29.aspx>`_.
- it is not possible to execute subprocesses
- :meth:`~BaseEventLoop.add_reader` and :meth:`~BaseEventLoop.add_writer` only
accept file descriptors of sockets
:class:`ProactorEventLoop` specific limits:
- SSL is not supported: :meth:`~BaseEventLoop.create_connection` and
:meth:`~BaseEventLoop.create_server` cannot be used with SSL for example
- :meth:`~BaseEventLoop.create_datagram_endpoint` (UDP) is not supported
- :meth:`~BaseEventLoop.add_reader` and :meth:`~BaseEventLoop.add_writer` are
not supported
The resolution of the monotonic clock on Windows is usually around 15.6 msec.
The best resolution is 0.5 msec. The exact resolution depends on the hardware
(availability of HPET) and the Windows configuration. See :ref:`asyncio delayed
calls <asyncio-delayed-calls>`.
Mac OS X
^^^^^^^^
Character devices like PTY are only well supported since Mavericks (Mac OS
10.9). They are not supported at all on Mac OS 10.5 and older.
On Mac OS 10.6, 10.7 and 10.8, the default event loop is
:class:`SelectorEventLoop` which uses :class:`selectors.KqueueSelector`.
:class:`selectors.KqueueSelector` does not support character devices on these
versions. The :class:`SelectorEventLoop` can be used with
:class:`~selectors.SelectSelector` or :class:`~selectors.PollSelector` to
support character devices on these versions of Mac OS X. Example::
import asyncio
import selectors
selector = selectors.SelectSelector()
loop = asyncio.SelectorEventLoop(selector)
asyncio.set_event_loop(loop)
Event loop policies and the default policy
------------------------------------------
Event loop management is abstracted with a *policy* pattern, to provide maximal
flexibility for custom platforms and frameworks. Throughout the execution of a
process, a single global policy object manages the event loops available to the
process based on the calling context. A policy is an object implementing the
:class:`AbstractEventLoopPolicy` interface.
For most users of :mod:`asyncio`, policies never have to be dealt with
explicitly, since the default global policy is sufficient.
The default policy defines context as the current thread, and manages an event
loop per thread that interacts with :mod:`asyncio`. The module-level functions
:func:`get_event_loop` and :func:`set_event_loop` provide convenient access to
event loops managed by the default policy.
Event loop policy interface
---------------------------
An event loop policy must implement the following interface:
.. class:: AbstractEventLoopPolicy
.. method:: get_event_loop()
Get the event loop for the current context. Returns an event loop object
implementing the :class:`BaseEventLoop` interface, or raises an exception in case
no event loop has been set for the current context and the current policy
does not specify to create one. It should never return ``None``.
.. method:: set_event_loop(loop)
Set the event loop for the current context to *loop*.
.. method:: new_event_loop()
Create and return a new event loop object according to this policy's rules.
If there's need to set this loop as the event loop for the current context,
:meth:`set_event_loop` must be called explicitly.
Access to the global loop policy
--------------------------------
.. function:: get_event_loop_policy()
Get the current event loop policy.
.. function:: set_event_loop_policy(policy)
Set the current event loop policy. If *policy* is ``None``, the default
policy is restored.

View File

@ -3,18 +3,18 @@
Subprocess
==========
Operating system support
------------------------
Windows event loop
------------------
On Windows, the default event loop uses :class:`selectors.SelectSelector`
which only supports sockets. The :class:`ProactorEventLoop` should be used to
support subprocesses. However, the latter does not support SSL.
On Windows, the default event loop is :class:`SelectorEventLoop` which does not
support subprocesses. :class:`ProactorEventLoop` should be used instead.
Example to use it on Windows::
On Mac OS X older than 10.9 (Mavericks), :class:`selectors.KqueueSelector`
does not support character devices like PTY, whereas it is used by the
default event loop. The :class:`SelectorEventLoop` can be used with
:class:`SelectSelector` or :class:`PollSelector` to handle character
devices on Mac OS X 10.6 (Snow Leopard) and later.
import asyncio, os
if os.name == 'nt':
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
Create a subprocess: high-level API using Process

View File

@ -45,6 +45,7 @@ Table of content:
:maxdepth: 3
asyncio-eventloop.rst
asyncio-eventloops.rst
asyncio-task.rst
asyncio-protocol.rst
asyncio-stream.rst