【问题标题】:When await will suspend the execution of an awaitable object in python?什么时候 await 将暂停 python 中等待对象的执行?
【发布时间】:2021-09-15 23:28:36
【问题描述】:

我已阅读When will/won't Python suspend execution of a coroutine?,接受的anwser提到:

值得一提的是,asyncio.sleep 明确保证暂停执行并推迟到事件循环,即使指定的延迟为 0(在这种情况下,它会在下一个事件循环通过时立即恢复)。”

来自python文档https://docs.python.org/3/library/asyncio-dev.html#concurrency-and-multithreading

当一个任务执行一个等待表达式时,正在运行的任务被挂起,事件循环执行下一个任务。

但在我下面的例子中,当它在do_something 中遇到await asyncio.sleep(0.1) 时并没有暂停,我的理解有什么问题?

import asyncio

async def do_something(i):
    await asyncio.sleep(0.1)
    print('in do_something')
    

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


t1 = time.time()

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
print('cost time:', time.time() - t1)

预期输出:

0
1
2
3
4
5
6
7
8
9
in do_something
in do_something
in do_something
in do_something
in do_something
in do_something
in do_something
in do_something
in do_something
in do_something
cost time: 1.0283539295196533

实际输出:

in do_something
1
in do_something
2
in do_something
3
in do_something
4
in do_something
5
in do_something
6
in do_something
7
in do_something
8
in do_something
9
in do_something
cost time: 1.0283539295196533

【问题讨论】:

  • do_something 等待 sleepmain 等待 do_somethingmain 中的循环不会继续,直到 do_something 完成,当 sleep 完成时完成。只要你await do_something,基本都是同步执行的。
  • @deceze 感谢您的帮助,我错误地认为这是一个异步调用。
  • 一个异步调用,从某种意义上说,控制在睡眠期间被传递给事件循环,并且它将执行其他任务 - 如果有的话。例如,如果将loop.run_until_complete(main()) 更改为loop.run_until_complete(asyncio.gather(main(), main())),您会观察到两个main 是并行执行的。正如文档所说,await 的意思是“调用这个异步函数,并暂停我直到它完成”。所以“等待”的意思是“等待”,如果你只有一个任务,等待会让一切看起来都是同步的。
  • 您可以将await do_something(i) 更改为asyncio.create_task(do_something(i)),并在main 末尾添加await asyncio.sleep(10)(以防止程序结束),您应该会看到预期的输出。
  • @user4815162342 谢谢,这是一个明确的答案!

标签: python async-await python-asyncio


【解决方案1】:

但在我下面的例子中,它在do_something 中遇到await asyncio.sleep(0.1) 时并没有暂停

它确实挂起,因为控制在睡眠期间被传递给事件循环,允许它执行其他任务 - 如果有的话。要看到这一点,请将loop.run_until_complete(main()) 更改为loop.run_until_complete(asyncio.gather(main(), main())),您会观察到两个 main 是并行执行的。

正如文档所说,await 的意思是“调用此异步函数,并暂停我直到它完成”。所以“等待”意味着“等待”,如果你只有一个任务,等待会让一切看起来都是同步的。您可以将await do_something(i) 更改为asyncio.create_task(do_something(i)),并在main 末尾添加await asyncio.sleep(10) (以防止程序结束),您应该会看到预期的输出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-15
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多