Issue
Can the eventloop switch between coroutines:
- when async method is awaited (called), before it executes?
- when async method is awaited (called), after it executes?
Here is an example:
async def some_slow_method():
total = 0.0
for i in range(1, 10000):
for j in range(1, 10000):
total += (i / j)
return total
async def the_caller():
# can the evenloop switch to another coroutine, between here...
result = await some_slow_method()
# ...and here?
(I find the documentation unclear on exactly this point)
Solution
The event loop can't switch to other coroutines await
unless the awaited coroutine (or other awaitable) chooses to suspend. Since some_slow_method
doesn't contain a single await
, it will never suspend and therefore the_caller()
will never switch to another coroutine. The fact that the event loop doesn't always suspend on await
is sometimes a source of bugs, as discussed here.
You can force some_slow_method
to occasionally switch to other coroutines using await asyncio.sleep(0)
, but that is considered bad style because the asyncio thread should avoid doing CPU work. If you must do CPU-bound work, a better option is to make some_slow_method
an ordinary def
and run it using await loop.run_in_executor(None, some_slow)
. This will hand it off to a thread pool, suspend the current coroutine, and wake it up once the function has completed, transferring its return value (or exception if one was raised).
Answered By - user4815162342
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.