我对 python 中的 asyncio 有点陌生。我试图运行这个简单的代码,但我不知道为什么我会得到这个意外的输出。
我所做的是,在
outer
函数中,我创建了异步任务并将其存储在数组tasks
中。在等待这些任务之前,我编写了一条打印语句print("outer")
,该语句应该在每次迭代中运行。在任务中,我在 print("inner")
函数中编写了另一个打印语句 inner
。但我如何得到一些意想不到的输出。
这是代码 -
import asyncio
def main():
loop = asyncio.get_event_loop()
loop.run_until_complete(outer(loop))
loop.close()
async def outer(loop):
tasks = []
for i in range(0, 5):
tasks.append(loop.create_task(inner()))
for task in tasks:
print("outer")
await task
async def inner():
print("inner")
await asyncio.sleep(0.5)
if __name__ == '__main__':
main()
这是输出 -
outer
inner
inner
inner
inner
inner
outer
outer
outer
outer
我的预期输出是 -
outer
inner
outer
inner
outer
inner
outer
inner
outer
inner
为什么所有的
inner
都在outer
之前打印。 asyncio的正确执行流程是怎样的?预先感谢。
在
async def outer(loop)
for i in range(0, 5):
tasks.append(loop.create_task(inner()))
inner
任务已创建、计划并开始运行。如果您在
inner
和 outer
上添加一点内容,它会更好地显示此过程:
async def outer(loop):
tasks = []
for i in range(0, 5):
tasks.append(loop.create_task(inner(i)))
await asyncio.sleep(3)
for task in tasks:
print('outer')
await task
async def inner(n):
print(f"inner {n} start")
await asyncio.sleep(0.5)
print(f'inner {n} end')
当
outer
睡觉时
您可以看到五个任务在第二个 for 循环开始之前就执行并完成了。
在第二个 for 循环中,每个任务都已完成,因此
await task
无需等待,outer
会连续打印五次。
我对控制一切的事件循环有点模糊 - 我还没有找到任何明确的文档 - 可能在
create_task
文档中提到:Wrap the coro coroutine into a Task and schedule its execution.
当您创建任务时,它会被安排。我在 pyvideo.org 上看过显示该过程的视频,不幸的是我无法快速找到我想要链接的视频。
loop.create_task(inner())
立即将所有 5 个inner
任务排队等待运行,而不是await task
。 await task
会暂停 outer
,直到第一个任务完全 完成,即至少 0.5 秒。在此期间,所有 inner
任务都已运行一次 await
,包括它们的 print
。
async def outer(loop):
tasks = []
for i in range(0, 5):
# queues task immediately
tasks.append(loop.create_task(inner()))
for task in tasks:
print("outer")
# suspends for at least 0.5 seconds
await task
async def inner():
# runs immediately
print("inner")
await asyncio.sleep(0.5)