0
votes

According to https://realpython.com/async-io-python/,

The keyword await passes function control back to the event loop. (It suspends the execution of the surrounding coroutine.) If Python encounters an await f() expression in the scope of g(), this is how await tells the event loop, “Suspend execution of g() until whatever I’m waiting on—the result of f()—is returned. In the meantime, go let something else run.”

import asyncio
import time

async def spend_time(name):
    print(f"spending time for {name}")
    for i in range(5):
        time.sleep(1)
        print(f"{name} sleep {i}")


async def first():
    print("first task...")
    await spend_time("first")
    print("first task finished")

async def second():
    print("second task...")
    await spend_time("second")
    print("second task finished")
loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(first(), second()))

For code above, I expect that after printing "first task", it will give control to another coroutines and print "second task", because it await, but it's not.

first task...
spending time for first
first sleep 0
first sleep 1
first sleep 2
first sleep 3
first sleep 4
first task finished
second task...
spending time for second
second sleep 0
second sleep 1
second sleep 2
second sleep 3
second sleep 4
second task finished

Why doesn't it suspend the execution of first task?

1

1 Answers

0
votes

time.sleep is a blocking call (it doesn't return the control back to the event loop), you should use asyncio.sleep instead:

import asyncio

async def spend_time(name):
    print(f"spending time for {name}")
    for i in range(5):
        await asyncio.sleep(1) # awaiting, returning the control
        print(f"{name} sleep {i}")


async def first():
    print("first task...")
    await spend_time("first")
    print("first task finished")


async def second():
    print("second task...")
    await spend_time("second")
    print("second task finished")


loop = asyncio.get_event_loop()
loop.run_until_complete(asyncio.gather(first(), second()))
loop.close()

Output:

first task...
spending time for first
second task...
spending time for second
first sleep 0
second sleep 0
first sleep 1
second sleep 1
first sleep 2
second sleep 2
first sleep 3
second sleep 3
first sleep 4
first task finished 
second sleep 4      
second task finished