Issue
Complete newb here, reading about Asycnio Tasks which has this example:
import asyncio
import time
async def say_after(delay, what):
await asyncio.sleep(delay)
print(what)
async def main():
task1 = asyncio.create_task(
say_after(1, 'hello'))
task2 = asyncio.create_task(
say_after(2, 'world'))
print(f"started at {time.strftime('%X')}")
# Wait until both tasks are completed (should take
# around 2 seconds.)
await task1
await task2
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
My original understanding of await
is that it blocks the execution of current function and wait for the async function to return.
But in this case both coroutines are executed concurrently, it doesn't fit well my understanding of await
. Could someone please explain?
Further investigation, by adding extra print
in say_after
, it seems to me the coroutine doesn't start until await
happens...
import asyncio
import time
async def say_after(delay, what):
print('Received {}'.format(what))
await asyncio.sleep(delay)
print(what)
async def main():
task1 = asyncio.create_task(
say_after(1, 'hello'))
task2 = asyncio.create_task(
say_after(2, 'world'))
print(f"started at {time.strftime('%X')}")
# Wait until both tasks are completed (should take
# around 2 seconds.)
await task1
await task2
print(f"finished at {time.strftime('%X')}")
asyncio.run(main())
prints
started at 13:41:23
Received hello
Received world
hello
world
finished at 13:41:25
Solution
When you encapsulate a coroutine in a Task (or Future) object the coroutine is ready to work, so when the event loop start running on the first await, both task1 and task2 are running.
Trying to make it clearer, to execute a coroutine you need two things:
1) a coroutine incapsulated in a future object(Task) to make it awaitable
2) a running event loop
In your example the execution works like this:
1 - create_task1
2 - create_task2
3 - await task1
4 - await sleep of task1
5 - await sleep of task2
now both task1 and task2 are sleeping so, suppose task1 is the first to finish (sleep some time)
6 - print of task1
7 - await task2
8 - print of task2
now the loop end
As you said when you got an await the execution stops, but let me say that stops just in the current "execution flow", when you create a future(Task) you create another exucution flow, and the await just switch to the current execution flow. This last explanation is not completely correct in sens of terms but help to make it clearer.
I hope i was clear. P.S.: sorry for my bad english.
Answered By - Fanto
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.