Issue
I have a following code:
def a:
parts = asyncio.run(b())
print(parts)
async def b():
res = await asyncio.gather(*c(i) for i in range(4))
async def c(i):
for j in range(5):
print(j, end=' ')
return i
I want c() to execute four times at the same time. Yet timing the funcions, as well as the logs, suggest that they are exeucting sequentially:
0 1 2 3 4 0 1 2 3 4 0 1 2 3 4 0 1 2 3 4
[0, 1, 2, 3]
How can I change the code so that the c() method is running 4 times in parallel?
Solution
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.
Answered By - HTF
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.