11.. _a-conceptual-overview-of-asyncio :
22
33****************************************
4- A Conceptual Overview of :mod: `!asyncio `
4+ A conceptual overview of :mod: `!asyncio `
55****************************************
66
77This :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`:
3737the event loop, coroutine functions, coroutine objects, tasks, and ``await ``.
3838
3939==========
40- Event Loop
40+ Event loop
4141==========
4242
4343Everything 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.
4546It's like an orchestra conductor.
46- It's behind the scenes managing resources.
4747Some 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
5050In more technical terms, the event loop contains a collection of jobs to be run.
5151Some 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
5959onwards.
6060If there are no more jobs pending execution, the event loop is smart enough to
6161rest 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
6464Effective execution relies on jobs sharing well and cooperating; a greedy job
6565could 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
170170functions) tied to an event loop.
171171A task also maintains a list of callback functions whose importance will become
172172clear in a moment when we discuss :keyword: `await `.
173- The recommended way to create tasks is via :func: `asyncio.create_task `.
174173
175174Creating a task automatically schedules it for execution (by adding a
176175callback 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::
250250In a crucial way, the behavior of ``await `` depends on the type of object
251251being awaited.
252252
253+ ^^^^^^^^^^^^^^
254+ Awaiting tasks
255+ ^^^^^^^^^^^^^^
256+
253257Awaiting a task will cede control from the current task or coroutine to
254258the event loop.
255259In the process of relinquishing control, a few important things happen.
@@ -281,6 +285,10 @@ This is a basic, yet reliable mental model.
281285In practice, the control handoffs are slightly more complex, but not by much.
282286In 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
285293loop! **
286294Wrapping 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.
348356Each time a task is awaited, control needs to be passed all the way up the
349357call 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------------------------------------------------
354364A conceptual overview part 2: the nuts and bolts
@@ -364,7 +374,8 @@ and how to make your own asynchronous operators.
364374The 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
370381resume 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=======
456467Futures
0 commit comments