Reputation: 1
I started learning python asyncio module. I was writing a basic program which basically waits for some time an prints the result.
async def say_helloworld(wait:int)->None:
print(f"starting say_helloworld({wait})")
await asyncio.sleep(wait)
print(f"say_helloworld({wait}) says hello world!")
I wrote my coroutine as given above and created some tasks.
tasks = (asyncio.create_task(say_helloworld(i)) for i in range(10))
I then wrapped the tasks in another coroutine.
async def main(tasks):
for task in tasks:
await task
Finally, I ran the wrapper coroutine
asyncio.run(main(tasks))
My expectation was that the program will finish in around 10 seconds, since each task will wait concurrently, and not in a synchronous fashion. But, the program nearly took 45 seconds (synchronous?). What am I missing? Why is it running like a synchronous program?
Upvotes: 0
Views: 194
Reputation: 154876
I wrote my coroutine as given above and created some tasks.
The problem is that your code, as written, doesn't actually create tasks in advance, it just provides a recipe how to create them when needed. tasks
is initialized to:
tasks = (asyncio.create_task(say_helloworld(i)) for i in range(10))
The above is a generator expression that will only create tasks as you iterate over it. So, while the intention was to create tasks in advance and then await them while they run in parallel, the actual implementation creates a single task in each iteration, and then awaits it immediately. This of leads to the undesirable result of the tasks being executed sequentially.
The fix is to build an actual list by switching from (asyncio.create_task... )
to [asyncio.create_task... ]
. You will also need to do so inside a coroutine so there is an event loop running for the tasks. For example:
# ... say_helloworld defined as before ...
async def main():
tasks = [asyncio.create_task(say_helloworld(i)) for i in range(10)]
for task in tasks:
await task
asyncio.run(main())
This results in ten "starting ..." messages followed a single pause and ten "says hello..." messages, which was the initial goal.
Upvotes: 3