gpt4 book ai didi

python - Asyncio 如何使用 run_forever?

转载 作者:太空宇宙 更新时间:2023-11-03 14:43:16 26 4
gpt4 key购买 nike

我想做的事情:

  1. 有一个启动的异步事件循环
  2. 该循环被传递到我的系统中的各个类,用于调度协程
  3. 该循环还用于处理对事件的响应(即,我有一个队列,一些事件处理代码将在该队列上放置一个项目,并在该队列上等待 get() 的独立协程来处理这些值(value)观)
  4. 有一个“拥有”循环并负责创建循环的主线程,在系统关闭时将取消循环中所有正在运行的任务并关闭并停止循环(干净地关闭)

我的理解是因为#3,需要在循环中调用 run_forever() 以确保在循环中安排任务。但是,如果我调用 run_forever(),那么我的主线程就会阻塞,永远不会终止。

我尝试过的:

产生一个线程,传入循环,然后在线程中调用run_forever。这意味着我的单元测试永远不会完成。要点:

def __start_background_loop(loop):
def run_forever(loop):
loop.run_forever()

# because run_forever() will block the current thread, we spawn
# a subthread to issue that call in.
thread = Thread(target=run_forever, args=(loop,))
thread.start()

def __end_background_loop(loop):
for task in Task.all_tasks(loop):
task.cancel()
loop.stop()

最佳答案

有两种可能的方法:您可以在主线程或后台线程中运行事件循环。如果您在主线程中运行它,您需要 run_forever(或 run_until_complete(main()) 或等价物)作为程序初始化的最后一步。在那种情况下,主线程将“阻塞”,但这没关系,因为它的事件循环将处于事件状态并响应外部事件,从而使程序能够运行。对分派(dispatch)协程和回调的事件循环的单个“阻塞”调用是 asyncio 的设计运行方式。

在这不切实际的情况下,例如包含大量同步代码的程序,或者已经在多个线程之间通信的程序,创建一个专用线程并在其中运行事件循环通常是更好的主意。在这种情况下,您必须非常小心,不要与事件循环通信,除非调用 loop.call_soon_threadsafe()。和 asyncio.run_coroutine_threadsafe() .例如,__end_background_loop 必须使用 loop.call_soon_threadsafe(__end_background_loop) 调用,因为它与任务和事件循环交互。这适用于与事件循环的所有交互 - 例如,不允许从另一个线程调用 loop.stop(),它必须拼写为 loop.call_soon_threadsafe(loop.stop)。当然,从 asyncio 回调和协程调用循环函数是可以的,因为它们将始终在运行事件循环的同一线程中运行。

关于python - Asyncio 如何使用 run_forever?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51642267/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com