3

I'm a python beginner and taking from https://www.youtube.com/watch?v=iG6fr81xHKA&t=269s about the power of asyncio, I tried to use this example shown and repurpose it to execute 10 times. Here's a code snippet

def main(x):
    print("Hello")
    time.sleep(3)
    print("World!")

And so I tried to do it in a asyncio fashion however it doesn't execute asynchronously. Here's so far what I've tried. What am I doing wrong?

import time
import asyncio


async def main(x):
    print(f"Starting Task {x}")
    await asyncio.sleep(3)
    print(f"Finished Task {x}")


async def async_io():
    for i in range(10):
        await main(i)

if __name__ == "__main__":
    start_time = time.perf_counter()
    asyncio.run(async_io())
    print(f"Took {time.perf_counter() - start_time} secs")

I've also tried to use queue_task in asyncio.

meh
  • 88
  • 6

1 Answers1

5

Using await, by definition, waits for the task main to finish. So your code as-is is no different from the synchronous code you posted above. If you want to run them at the same time (asynchronously), while waiting for the results, you should use asyncio.gather or asyncio.wait instead.

async def async_io():
    tasks = []
    for i in range(10):
        tasks += [main(i)]
    await asyncio.gather(*tasks)

If you don't care to wait for all of the main() calls to finish, you can also just use asyncio.create_task(main(i)), which creates a Task object and schedule its execution in the background. In this case, def async_io() doesn't need to be async anymore.

Taku
  • 31,927
  • 11
  • 74
  • 85
  • How does the code work? – meh Oct 23 '21 at 01:14
  • 1
    This saves all of the `main(i)` coroutines into a list (`tasks`), and `asyncio.gather` schedules all of the coroutines into the event loop and waits for it to finish then returns the result. – Taku Oct 23 '21 at 01:18
  • 1
    If you don't understand coroutines: Unlike normal functions that it executes the function body when you call the function, an async function returns a coroutine instead. Coroutines gets executed when you "await" for its execution or scheduled as a `Task` on the event loop. In my case, I awaited for `asyncio.gather()` which in turn creates `Task`'s for the list of coroutines (`tasks`), schedules them on the event loop and awaits for them to conclude. – Taku Oct 23 '21 at 01:26
  • Is there a good code example that demonstrates scheduling tasks like you mentioned (without asyncio.gather)? – meh Oct 23 '21 at 01:50
  • 1
    Hmm maybe checkout the usage of create_task in this question https://stackoverflow.com/questions/37278647/fire-and-forget-python-async-await – Taku Oct 23 '21 at 02:09