In this document of Asyncio, we can see it use await asyncio.sleep(1)
to delay 1 second and then cancel the task.
And I try to change it to await asyncio.sleep(0)
, it works well too.
But when I try to delete await asyncio.sleep(1)
, the program seems wouldn't enter the func cancel_me
. So it just appear main(): cancel_me is cancelled now
in the cli.
What is the reason for this?
asyncio
coroutines aren't executed by themselves, they're executed by event loop.
Event loop receives control on asyncio.run
and starts to execute some coroutine. When execution flow reaches something blocking like await asyncio.sleep()
or await future
it return control back to event loop. It allows event loop to start or resume execution of something else.
Take a look at example and picture here to see it on simple example.
In the example about cancel()
following happen:
await asyncio.sleep(0)
as well as 1
will return control to event loop
- Event loop will start to execute
cancel_me()
cancel_me()
eventually will stumble on something blocking and return control back to event loop
- Event loop will resume execution of
main()
main()
will mark task to be cancelled with task.cancel()
and await it cancelled with await task
If you however don't have asyncio.sleep()
on step one, execution flow won't even reach cancel_me()
because event loop never received control between tasks creation and task cancellation. When event loop reaches await task
it sees task was never started and mark for cancellation: there's no sense to start it now.