繁体   English   中英

Asyncio您如何使用run_forever?

[英]Asyncio How do you use run_forever?

我想做的事:

  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()

有两种可能的方法:您可以在主线程或后台线程中运行事件循环。 如果在主线程中运行它,则需要在程序初始化的最后一步中运行run_forever (或run_until_complete(main())或同等功能)。 在那种情况下,主线程将“阻塞”,但这是可以的,因为它的事件循环将继续运行并响应外部事件,从而允许程序运行。 分派协程和回调的事件循环的单个“阻塞”调用是设计异步运行的方式。

在不切实际的情况下,例如包含大量同步代码的程序,或者已经在多个线程之间进行通信的程序,通常最好创建一个专用线程并在其中运行事件循环。 在那种情况下,除了要调用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回调和协程调用循环函数很好,因为它们将始终在与事件循环运行所在的线程中运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM