What does await
do?
Suspend the execution of coroutine on an awaitable object. Can only be used inside a coroutine function.
What does asyncio.gather
do?
- Run awaitable objects in the aws sequence concurrently. (Where aws is an iterable of awaitable objects)
- If any awaitable in aws is a coroutine, it is automatically scheduled as a Task.
When one uses the await
keyword - it causes the current coroutine to suspend execution at that point and wait for the awaitable to be done.
Coroutines are different from Tasks - but they are both awaitables.
Checking the types of the objects in the case presented:
$ python -m asyncio
>>> import asyncio
>>> type(asyncio.sleep(2))
<class 'coroutine'>
>>> type(asyncio.create_task(asyncio.sleep(2)))
<class '_asyncio.Task'>
Executing a coroutine or task directly with await
- will make the caller wait for it to complete.
The difference with a task is that on creation of the task with asyncio.create_task
the task is scheduled (and executed if the event loop is not busy). So oftentimes when the awaiting happens the task is already complete.
An alternate way to run the tasks without using asyncio.gather
is by creating tasks with asyncio.create_task
. This will achieve the ~6 second result.
async def async_sleep(n):
task_sleep_1 = asyncio.create_task(asyncio.sleep(n+2))
task_sleep_2 = asyncio.create_task(asyncio.sleep(n))
await task_sleep_1
await task_sleep_2
Clarifications:
- There is no parallel at all when talking
asyncio
. Only context switching.
- The tasks will run in sequence - in sequence concurrently / overlapping. Not waiting for a result until moving on (blocking).
Sources: