Home > Software engineering >  Execution order of tasks scheduled on an event loop (Python 3.10)
Execution order of tasks scheduled on an event loop (Python 3.10)

Time:03-17

I am still learning the asyncio module in python 3.10. Below is a code I wrote trying to understand how to run coroutines as tasks on an event loop. the output I am getting is different from what I expected. Please help me understand what I am doing wrong or if there is something I misunderstood.

import asyncio 
    async def f(x):
        try:
            print(f"Inside f({x})...")
            await asyncio.sleep(x)
            print(f'slept for {x} seconds!!')
            return x
        except asyncio.CancelledError:  # Execute this part only when the task is cancelled.
            print(f'Cancelled({x})')
    
    async def main():
        loop = asyncio.get_running_loop()
    
        task1 = loop.create_task(f(1), name="task1")
        task2 = loop.create_task(f(2), name="task2")
        task3 = loop.create_task(f(3), name="task3")
    
        print(task1.done())
        print(task2.done())
        print(task3.done())
    
    asyncio.run(main())

Output:

False False False Inside f(1)... Inside f(2)... Inside f(3)... Cancelled(3) Cancelled(1) Cancelled(2)

I expect this code to exit main() immediately after print(task3.done()) and only run the exception handling part of the coroutine function f(x), but the event loop runs the functionalities of f(1), f(2) and f(3) exactly one time before actually exiting. My doubts are

  1. Why do all the tasks on the event loop run once before getting cancelled?
  2. What is the execution order (if there is any, is it fixed or random?)

Edit: I first tried using task1 = asyncio.create_task(f(1), name = "task1"). Then I used loop.create_task(). Both give same output(which is to be expected I guess).

CodePudding user response:

I think you should change the line "task1 = loop.create_task(f(1), name="task1")" to be "task1 = asyncio.create_task(f(1), name="task1")"

CodePudding user response:

Your program is finishing before your asynchronous tasks are done, so they are all being cancelled. The call to done() just prints that they're not done.

You need to add await(task1), etc. in addition to the previous answer if you want to give your tasks the chance to finish. Or just await asyncio.gather(task1, task2, task3) to wait for all of them in one call.

  • Related