首页 文章

为什么loop.run_forever()锁定我的主线程?

提问于
浏览
0

学习asyncio时我正在尝试这段代码:

import asyncio
from  asyncio.coroutines import coroutine

@coroutine
def coro():
    counter: int = 0

    while True:
        print("Executed" + str(counter))
        counter += 1
        yield


 loop = asyncio.get_event_loop()
 loop.run_until_complete(coro())
 loop.run_forever()

 print("Finished!")

我期待协程只执行一次,因为它包含一个yield并且应该将控制权返回给调用者 . 我期待的输出是:

Executed 0
Finished!

我期待这种行为,因为我认为循环将永远运行协程一旦每个“帧”在每次执行后返回到调用者(类似于后台线程,但以合作的方式) . 但相反,它会永远运行协程而不返回?输出如下:

Executed 0
Executed 1
Executed 2
Executed 3
...

谁能解释为什么会发生这种情况而不是我的期望?

干杯 .

1 回答

  • 1

    你有几个问题 . 当你调用 run_until_complete 时,它会等待 coro 完成,然后再继续你的 run_forever 调用 . 正如你所定义的那样, coro 永远不会完成 . 它包含一个无限循环,无法突破循环 . 如果要继续执行应用程序中的下一步,则需要在循环内的某处 breakreturn .

    但是,一旦你完成了这个,你的下一个电话就是 run_forever ,顾名思义,它将永远运行 . 在这种情况下,它赢得了't have anything to do because you' ve事件循环没有安排其他任何事情 .

    我期待协程只执行一次,因为它包含一个yield并且应该已经将控制权返回给调用者 .

    回顾一下你的协程没有产量的事实,等待(或根据你选择使用的语法产生的结果)不会将控制权返回给 run_until_completerun_forever 的调用者 . 它将控制返回到事件循环,以便它可以检查已经等待并准备恢复的任何其他内容 .

相关问题