【发布时间】: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等待sleep,main等待do_something。main中的循环不会继续,直到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