Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 16 additions & 15 deletions Doc/library/asyncio-dev.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ To enable all debug checks for an application:
* Enable the asyncio debug mode globally by setting the environment variable
:envvar:`PYTHONASYNCIODEBUG` to ``1``, using ``-X dev`` command line option
(see the :option:`-X` option), or by calling
:meth:`AbstractEventLoop.set_debug`.
:meth:`loop.set_debug`.
* Set the log level of the :ref:`asyncio logger <asyncio-logger>` to
:py:data:`logging.DEBUG`. For example, call
``logging.basicConfig(level=logging.DEBUG)`` at startup.
Expand All @@ -35,11 +35,11 @@ Examples debug checks:

* Log :ref:`coroutines defined but never "yielded from"
<asyncio-coroutine-not-scheduled>`
* :meth:`~AbstractEventLoop.call_soon` and :meth:`~AbstractEventLoop.call_at` methods
* :meth:`loop.call_soon` and :meth:`loop.call_at` methods
raise an exception if they are called from the wrong thread.
* Log the execution time of the selector
* Log callbacks taking more than 100 ms to be executed. The
:attr:`AbstractEventLoop.slow_callback_duration` attribute is the minimum
:attr:`loop.slow_callback_duration` attribute is the minimum
duration in seconds of "slow" callbacks.
* :exc:`ResourceWarning` warnings are emitted when transports and event loops
are :ref:`not closed explicitly <asyncio-close-transports>`.
Expand All @@ -51,7 +51,7 @@ Examples debug checks:

.. seealso::

The :meth:`AbstractEventLoop.set_debug` method and the :ref:`asyncio logger
The :meth:`loop.set_debug` method and the :ref:`asyncio logger
<asyncio-logger>`.


Expand All @@ -75,7 +75,7 @@ For example, write::

Don't schedule directly a call to the :meth:`~Future.set_result` or the
:meth:`~Future.set_exception` method of a future with
:meth:`AbstractEventLoop.call_soon`: the future can be cancelled before its method
:meth:`loop.call_soon`: the future can be cancelled before its method
is called.

If you wait for a future, you should check early if the future was cancelled to
Expand All @@ -96,13 +96,14 @@ The :func:`shield` function can also be used to ignore cancellation.
Concurrency and multithreading
------------------------------

An event loop runs in a thread and executes all callbacks and tasks in the same
thread. While a task is running in the event loop, no other task is running in
the same thread. But when the task uses ``await``, the task is suspended
and the event loop executes the next task.
An event loop runs in a thread (typically the main thread) and executes
all callbacks and tasks in its thread. While a task is running in the
event loop, no other task is running in the same thread. When a task
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no other tasks may run in the...

executes an ``await`` expression, the task gets suspended and the
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the running task

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically the task can be suspended but if a future at the end of awaiting chain is ready no suspension is performed.

I described this behavior to many people. Stack Overflow also has questions like this.
Looks like we need to mention it here to avoid confusion.

event loop executes the next task.

To schedule a callback from a different thread, the
:meth:`AbstractEventLoop.call_soon_threadsafe` method should be used. Example::
:meth:`loop.call_soon_threadsafe` method should be used. Example::

loop.call_soon_threadsafe(callback, *args)

Expand All @@ -122,7 +123,7 @@ To schedule a coroutine object from a different thread, the
future = asyncio.run_coroutine_threadsafe(coro_func(), loop)
result = future.result(timeout) # Wait for the result with a timeout

The :meth:`AbstractEventLoop.run_in_executor` method can be used with a thread pool
The :meth:`loop.run_in_executor` method can be used with a thread pool
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ThreadPoolExecutor to execute a callback in a different thread so as not to block the event loop's main thread.

executor to execute a callback in different thread to not block the thread of
the event loop.

Expand Down Expand Up @@ -151,7 +152,7 @@ APIs like :ref:`protocols <asyncio-protocol>`.

An executor can be used to run a task in a different thread or even in a
different process, to not block the thread of the event loop. See the
:meth:`AbstractEventLoop.run_in_executor` method.
:meth:`loop.run_in_executor` method.

.. seealso::

Expand Down Expand Up @@ -182,7 +183,7 @@ Detect coroutine objects never scheduled
----------------------------------------

When a coroutine function is called and its result is not passed to
:func:`ensure_future` or to the :meth:`AbstractEventLoop.create_task` method,
:func:`ensure_future` or to the :meth:`loop.create_task` method,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we focus on asyncio.create_task() helper here?

the execution of the coroutine object will never be scheduled which is
probably a bug. :ref:`Enable the debug mode of asyncio <asyncio-debug-mode>`
to :ref:`log a warning <asyncio-logger>` to detect it.
Expand All @@ -204,7 +205,7 @@ Output in debug mode::
test()

The fix is to call the :func:`ensure_future` function or the
:meth:`AbstractEventLoop.create_task` method with the coroutine object.
:meth:`loop.create_task` method with the coroutine object.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asyncio.create_task() again?


.. seealso::

Expand Down Expand Up @@ -279,7 +280,7 @@ coroutine in another coroutine and use classic try/except::
loop.run_forever()
loop.close()

Another option is to use the :meth:`AbstractEventLoop.run_until_complete`
Another option is to use the :meth:`loop.run_until_complete`
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we promote asyncio.run() here?

function::

task = asyncio.ensure_future(bug())
Expand Down
Loading