python-asyncio - 为什么 loop.run_forever() 会锁定我的主线程?
问题描述
在学习 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
...
谁能解释为什么会发生这种情况而不是我的期望?
干杯。
解决方案
你有几个问题。当您拨打电话时run_until_complete
,它会等待coro
完成,然后再继续您的run_forever
通话。正如您定义的那样,coro
永远不会完成。它包含一个无限循环,对跳出循环没有任何作用。如果您想继续应用程序的下一步,则需要在循环内的某个地方使用 abreak
或 a 。return
但是,一旦你完成了这些,你的下一个调用是 to run_forever
,正如它的名字所暗示的那样,它将永远运行。在这种情况下,它不会有任何事情要做,因为您没有为事件循环安排其他任何事情。
我希望协程只执行一次,因为它包含一个 yield 并且应该将控制权返回给调用者。
回顾您的协程没有屈服的事实,等待(或屈服取决于您选择使用的语法)不会将控制权返回给 or 的调用run_until_complete
者run_forever
。它将控制权返回给事件循环,以便它可以检查已等待并准备恢复的任何其他内容。
推荐阅读
- c# - 将 2D 列表写入文件错误:System.InvalidOperationException:
- wordpress - 发送链接时我的图像未显示
- mysql - 如何选择字符串的所有更长、更短的版本,以及字符串本身
- c++ - C ++钩子键盘键按下并释放键
- python-3.x - 在 python3 中通过套接字发送 .mp4 文件
- node.js - nodemon 和 live-server 有什么区别?
- r - 不正确地将chr转换为R中的数字变量
- c++ - 由 glUniformMatrix4fv 创建时,Uniform mat4 具有未知值
- python - 计算图像中对象的中心
- java - 在主机对象上设置方法