When Will/won't Python Suspend Execution Of A Coroutine?
Solution 1:
This behavior (printing hello world a single time) makes sense to me, because
hog_the_event_loop
never blocks and therefore has no need to suspend execution. Can I rely on this behavior?
Yes. This behavior directly follows from how await
is both specified and implemented by the language. Changing it to suspend without the awaitable object having itself suspended would certainly be a breaking change, both for asyncio and other Python libraries based in async/await.
Put more generally: When will python suspend execution of a coroutine and switch to another one? Is it potentially on any use of the
await
keyword?
From the caller's perspective, any await
can potentially suspend, at the discretion of the awaited object, also known as an awaitable. So the final decision of whether a particular await
will suspend is on the awaitable (or on awaitables it awaits itself if it's a coroutine, and so on). Awaiting an awaitable that doesn't choose to suspend is the same as running ordinary Python code - it won't pass control to the event loop.
The leaf awaitables that actually suspend are typically related to IO readiness or timeout events, but not always. For example, awaiting a queue item will suspend if the queue is empty, and awaiting run_in_executor
will suspend until the function running in the other thread completes.
It is worth mentioning that asyncio.sleep
is explicitly guaranteed to suspend execution and defer to the event loop, even when the specified delay is 0 (in which case it will immediately resume on the next event loop pass).
Solution 2:
No, await do_nothing()
will never suspend. await
propagates suspension from an awaitable by suspending the surrounding coroutine in response. But when the awaitable is already ready, there’s nothing to wait for and execution continues from the await
(with a return value, in general). A nother way of thinking about “nothing to wait for” is that the event loop literally has no object on which to base the timing of resuming from a notional suspension; even “resume as soon as other pending tasks suspend” is a schedule that would have to be expressed as some object (e.g., sleep(0)
).
A coroutine that does nothing is always ready, just like one that sleeps is ready after the time elapses. Put differently, a coroutine that just sleeps N times suspends N times—even if N is 0.
Post a Comment for "When Will/won't Python Suspend Execution Of A Coroutine?"