【问题标题】:Asyncio How do you use run_forever?Asyncio 如何使用 run_forever?
【发布时间】:2018-08-28 00:11:33
【问题描述】:

我想做什么:

  1. 有一个启动的异步事件循环
  2. 该循环被传递给我系统中的各个类,用于调度协程
  3. 该循环还用于处理对事件的响应(即,我有一个队列,一些事件处理代码将在该队列上放置一个项目,并在该队列上等待 get() 处理的单独协程这些值)
  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()

【问题讨论】:

  • 为什么不在另一个线程中创建事件循环呢? asyncio.new_event_loop()

标签: python python-asyncio


【解决方案1】:

有两种可能的方法:您可以在主线程或后台线程中运行事件循环。如果您在主线程中运行它,您需要将run_forever(或run_until_complete(main()) 或等效项)作为程序初始化的最后一步。在这种情况下,主线程将“阻塞”,但这没关系,因为它的事件循环将是活动的并响应外部事件,从而允许程序运行。对调度协程和回调的事件循环的单个“阻塞”调用是 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 回调和协程调用循环函数很好,因为它们将始终在事件循环运行的同一线程中运行。

【讨论】:

  • “从另一个线程调用 loop.stop() 甚至是不安全的”——如果不是从另一个线程调用,循环如何停止?或者你的意思是从另一个线程调用call_soon_threadsafe(loop.stop()) 是安全的,而不是直接调用loop.stop()
  • @AdamParkin 循环可以从事件循环线程中的回调或协程中停止——例如,协程可以检测到套接字上的“退出”命令并调用loop.stop()。当图片中只有一个线程并且它只运行事件循环时,事情就是这样工作的,这是 asyncio 的一种完全有效(甚至是典型)的用法。如果你确实使用了多个线程,那么所有其他线程都必须调用 loop.stop() 作为loop.call_soon_threadsafe(loop.stop)(注意loop.stop 后面缺少括号),对于其他任何与循环相关的内容也是如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-24
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2023-02-02
  • 1970-01-01
  • 2018-01-07
相关资源
最近更新 更多