Adding just an async
keyword in front of a function doesn't make it asynchronous. You can try something like this:
test.py:
import asyncio
def a():
parts = asyncio.run(b())
print(parts)
async def b():
return await asyncio.gather(*(c(i) for i in range(4)))
async def c(i):
for j in range(5):
await asyncio.sleep(0)
print(j, end=' ')
return i
a()
Test:
python test.py
0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 [0, 1, 2, 3]
By adding asyncio.sleep(0)
forces the async function to yield control to the event loop and allows the other coroutines to run.
Update: Wed 17 Feb 15:25:50 UTC 2021
Python docs states the following:
An event loop runs in a thread (typically the main thread) and
executes all callbacks and Tasks in its thread. While a Task is
running in the event loop, no other Tasks can run in the same thread.
When a Task executes an await expression, the running Task gets
suspended, and the event loop executes the next Task.
So all tasks are running in a single thread and asyncio.sleep() always suspends the current task, allowing other tasks to run.
Please note that concurrency and parallelism are similar terms, but they are not the same thing if you need to run multiple tasks at the same time across multiple CPU cores use multiprocessing.