【问题标题】:Why loop.run_forever() is locking my main thread?为什么 loop.run_forever() 会锁定我的主线程?
【发布时间】:2018-04-26 14:07:35
【问题描述】:

在学习 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
...

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

干杯。

【问题讨论】:

  • 我希望协程只执行一次,因为它包含一个 yieldyield 在哪里?
  • 抱歉,我以某种方式在粘贴的代码中遗漏了产量。我又加了一次。感谢您发现它!

标签: python-asyncio coroutine event-loop


【解决方案1】:

你有几个问题。当您拨打run_until_complete 时,它会等待coro 完成,然后再继续您的run_forever 呼叫。正如您所定义的,coro 永远不会结束。它包含一个无限循环,对跳出循环没有任何作用。如果您想继续应用程序的下一步,则需要在循环内的某个位置使用 break 或 return。

不过,一旦你这样做了,你的下一个电话是run_forever,正如它的名字所暗示的那样,它将永远运行。在这种情况下,它不会有任何事情要做,因为您没有为事件循环安排其他任何事情。

我希望协程只执行一次,因为它包含一个 yield 并且应该将控制权返回给调用者。

回顾你的协程没有屈服的事实,等待(或屈服取决于你选择使用的语法)不会将控制权返回给run_until_complete或run_forever的调用者。它将控制权返回给事件循环,以便它可以检查任何其他已等待并准备恢复的内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 2011-03-25
    • 1970-01-01
    • 2016-06-26
    • 1970-01-01
    相关资源
    最近更新 更多