Skip to content

Commit b3b63e8

Browse files
pythongh-138072: Small clarifications and phrasing improvements to asyncio HOWTO (python#138073)
* - Small clarifications and phrasing improvements * nit * Apply suggestions from code review Co-authored-by: Peter Bierma <[email protected]> * clarify event loops when multi threading. * nit * Update Doc/howto/a-conceptual-overview-of-asyncio.rst Co-authored-by: Peter Bierma <[email protected]> * nit * nit * phrasing for threads & event loops. * revert changes to event-loop/thread discussion. * sentence case consistencty. * slight re-arrange. * Sentence case consistency. * tweak language. non-negligible --------- Co-authored-by: Peter Bierma <[email protected]>
1 parent 96f496a commit b3b63e8

File tree

1 file changed

+25
-14
lines changed

1 file changed

+25
-14
lines changed

Doc/howto/a-conceptual-overview-of-asyncio.rst

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. _a-conceptual-overview-of-asyncio:
22

33
****************************************
4-
A Conceptual Overview of :mod:`!asyncio`
4+
A conceptual overview of :mod:`!asyncio`
55
****************************************
66

77
This :ref:`HOWTO <how-tos>` article seeks to help you build a sturdy mental
@@ -37,15 +37,15 @@ In part 1, we'll cover the main, high-level building blocks of :mod:`!asyncio`:
3737
the event loop, coroutine functions, coroutine objects, tasks, and ``await``.
3838

3939
==========
40-
Event Loop
40+
Event loop
4141
==========
4242

4343
Everything in :mod:`!asyncio` happens relative to the event loop.
44-
It's the star of the show.
44+
It's the star of the show, but prefers to work behind the scenes, managing
45+
and coordinating resources.
4546
It's like an orchestra conductor.
46-
It's behind the scenes managing resources.
4747
Some power is explicitly granted to it, but a lot of its ability to get things
48-
done comes from the respect and cooperation of its worker bees.
48+
done comes from the respect and cooperation of its band members.
4949

5050
In more technical terms, the event loop contains a collection of jobs to be run.
5151
Some jobs are added directly by you, and some indirectly by :mod:`!asyncio`.
@@ -59,7 +59,7 @@ This process repeats indefinitely, with the event loop cycling endlessly
5959
onwards.
6060
If there are no more jobs pending execution, the event loop is smart enough to
6161
rest and avoid needlessly wasting CPU cycles, and will come back when there's
62-
more work to be done.
62+
more work to be done, such as when I/O operations complete or timers expire.
6363

6464
Effective execution relies on jobs sharing well and cooperating; a greedy job
6565
could hog control and leave the other jobs to starve, rendering the overall
@@ -170,14 +170,14 @@ Roughly speaking, :ref:`tasks <asyncio-task-obj>` are coroutines (not coroutine
170170
functions) tied to an event loop.
171171
A task also maintains a list of callback functions whose importance will become
172172
clear in a moment when we discuss :keyword:`await`.
173-
The recommended way to create tasks is via :func:`asyncio.create_task`.
174173

175174
Creating a task automatically schedules it for execution (by adding a
176175
callback to run it in the event loop's to-do list, that is, collection of jobs).
176+
The recommended way to create tasks is via :func:`asyncio.create_task`.
177177

178-
Since there's only one event loop (in each thread), :mod:`!asyncio` takes care of
179-
associating the task with the event loop for you. As such, there's no need
180-
to specify the event loop.
178+
Since there's only one event loop (in each thread), :mod:`!asyncio` takes
179+
care of associating the task with the event loop for you.
180+
As such, there's no need to specify the event loop.
181181

182182
::
183183

@@ -250,6 +250,10 @@ different ways::
250250
In a crucial way, the behavior of ``await`` depends on the type of object
251251
being awaited.
252252

253+
^^^^^^^^^^^^^^
254+
Awaiting tasks
255+
^^^^^^^^^^^^^^
256+
253257
Awaiting a task will cede control from the current task or coroutine to
254258
the event loop.
255259
In the process of relinquishing control, a few important things happen.
@@ -281,6 +285,10 @@ This is a basic, yet reliable mental model.
281285
In practice, the control handoffs are slightly more complex, but not by much.
282286
In part 2, we'll walk through the details that make this possible.
283287

288+
^^^^^^^^^^^^^^^^^^^
289+
Awaiting coroutines
290+
^^^^^^^^^^^^^^^^^^^
291+
284292
**Unlike tasks, awaiting a coroutine does not hand control back to the event
285293
loop!**
286294
Wrapping a coroutine in a task first, then awaiting that would cede
@@ -347,8 +355,10 @@ The design intentionally trades off some conceptual clarity around usage of
347355
``await`` for improved performance.
348356
Each time a task is awaited, control needs to be passed all the way up the
349357
call stack to the event loop.
350-
That might sound minor, but in a large program with many ``await`` statements and a deep
351-
call stack, that overhead can add up to a meaningful performance drag.
358+
Then, the event loop needs to manage its internal state and work through
359+
its processing logic to resume the next job.
360+
That might sound minor, but in a large program with many ``await``\ s, that
361+
overhead can add up to a non-negligible performance drag.
352362

353363
------------------------------------------------
354364
A conceptual overview part 2: the nuts and bolts
@@ -364,7 +374,8 @@ and how to make your own asynchronous operators.
364374
The inner workings of coroutines
365375
================================
366376

367-
:mod:`!asyncio` leverages four components to pass around control.
377+
:mod:`!asyncio` leverages four components of Python to pass
378+
around control.
368379

369380
:meth:`coroutine.send(arg) <generator.send>` is the method used to start or
370381
resume a coroutine.
@@ -448,9 +459,9 @@ That might sound odd to you. You might be thinking:
448459
That causes the error: ``SyntaxError: yield from not allowed in a coroutine.``
449460
This was intentionally designed for the sake of simplicity -- mandating only
450461
one way of using coroutines.
462+
Despite that, ``yield from`` and ``await`` effectively do the same thing.
451463
Initially ``yield`` was barred as well, but was re-accepted to allow for
452464
async generators.
453-
Despite that, ``yield from`` and ``await`` effectively do the same thing.
454465

455466
=======
456467
Futures

0 commit comments

Comments
 (0)