本文介绍了Asyncio执行流程问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对python中的asyncio有点陌生.我试图运行这个简单的代码,但是我不知道为什么我得到了这个意外的输出.

i am a little new to asyncio in python. I was trying to run this simple code but i don't know why i am getting this unexpected output.

我所做的是,在 outer 函数中,我创建了一个异步任务并将其存储在数组 tasks 中.在等待这些任务之前,我写了一个打印语句 print("outer"),该语句应在每次迭代中运行.在任务内部,我在 inner 函数中编写了另一个打印语句 print("inner").但是有一些我是如何得到一些意外输出的.

What i did is that, in outer function, i created async tasks and stored it in an array tasks. Before awaiting on these tasks i wrote a print statement print("outer") that should run in every iteration. And inside the task i wrote another print statement print("inner") in inner function. But some how i am getting some unexpected output.

这是代码-

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的正确执行流程.预先感谢.

Why all the inner are printing before outer. What is the correct execution flow of asyncio. Thanks in advance.

推荐答案

异步定义外部(循环)

for i in range(0, 5):
    tasks.append(loop.create_task(inner()))

  • 创建,安排并开始运行五个新的 inner 任务.
  • 事件循环会运行计划的任务,直到它们完成为止.
  • 如果在 inner outer 中添加更多内容,则可以更好地显示此过程:

    If you add a little bit more to to inner and outer it shows this process better:

    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')
    

    • 外部处于睡眠状态

      • 第一个任务运行到其等待语句
      • 事件循环暂停执行第一个任务
      • 事件循环运行下一个计划任务,直到其等待语句
      • 这种情况一直持续到每个任务都有机会执行其await语句,然后事件循环开始环顾四周,以查看是否有任何任务在等待它们的等待中完成-如果完成,则让它们运行一些更多.
      • 这一直持续到所有任务都完成为止
      • The first task runs to its await statement
      • The event loop suspends execution of the first task
      • The event loop runs the next schduled task up to its await statement
      • This continues till each task has had a chance to run up to its await statement then the event loop starts looking around to see if any of the tasks are done waiting for whatever they were waiting for - if done it lets them run some more.
      • This continues till all the tasks are done

      您可以看到五个任务在第二个for循环甚至开始之前就已执行并完成.

      You can see that the five tasks execute and finish before the second for loop even starts.

      我对控制所有内容的事件循环有些困惑-我还没有找到任何明确的文档-可能在 create_task 文档中提到:将coro协程包装到任务并安排其执行.创建任务时,将对其进行安排.我在pyvideo.org上观看了显示该过程的视频,很遗憾,我无法快速找到我想要链接的视频.

      I'm a little hazy on the event loop controlling everything - I haven't found any explicit documentation for that - probably alluded to in the create_task docs: Wrap the coro coroutine into a Task and schedule its execution. When you create the task it gets scheduled. I have seen videos on pyvideo.org that shows that process, unfortunately I couldn't quickly find the one I wanted to link to.

      这篇关于Asyncio执行流程问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-05 10:04