3

I'm trying to understand python asyncio lib, but it's a pain and each time I think i know how the code will behave, something suprises me.

I have the following code:

async def a():
    while True:
        task = asyncio.current_task()  # asyncio.Task.current_task()
        print(task.name)
        await asyncio.sleep(0.5)

async def main():
    tasks = []

    for i in range(10):
        c = a()
        task = asyncio.create_task(c)
        task.name = "task nr {}".format(i)
        tasks.append(task)

    for task in tasks:
        await task

asyncio.run(main())

Would result with the following output as suspected:

task nr 0
task nr 1
task nr 2
task nr 3
task nr 4
task nr 5
task nr 6
task nr 7
task nr 8
task nr 9

and so on. On the other hand I have a code

async def a():
    while True:
        task = asyncio.current_task()  # asyncio.Task.current_task()
        print(task.name)
        await asyncio.sleep(0.5)

async def main():

    for i in range(10):
        c = a()
        task = asyncio.create_task(c)
        task.name = "task nr {}".format(i)
        await task

asyncio.run(main())

This time it outputs just "task nr 0".

In the first one creates 10 tasks and then starst all of them. The second one merges those two loops - why it affects behaviour of the program?

0

2 Answers 2

2

The second one merges those two loops - why it affects behaviour of the program?

Because your first code runs create_task for all ten coroutines before getting to an await.

Since create_task schedules the execution of the coroutine, in the first example all ten coroutines are happily executing in parallel while you are awaiting the first one (which, as the other answer points out, will never complete because the coroutines are infinite). In the second loop you are only executing one create_task before the infinite await, so you only get one coroutine running.

If you are familiar with threads, perhaps the following analogy will help: You can think of create_task as spawning a thread, and await as joining it. In the first example you've spawned ten of them, and in the second only one.

Sign up to request clarification or add additional context in comments.

Comments

2

Your a() is an infinite coroutine. The process of awaiting it will never complete. Meaning that in your second snippet the for loop will never enter next iteration. It is basically "blocked" forever on await task.

3 Comments

Shouldn't this be true also in the first code snippet for the second for-loop?
@MichaelButscher it is, yes. But in the first code await runs after all tasks are already created.
I should have read the docs, create_task already runs the task, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.