【问题标题】:asyncio: 50ms delay between put_nowait and get to/from a queueasyncio:put_nowait 和 get 到/从队列之间有 50 毫秒的延迟
【发布时间】:2019-11-03 20:49:30
【问题描述】:

我有一个 python asyncio 应用程序,多个协程在一个线程中运行。一些数据正在使用队列传递。

队列消费者如下所示:

    async def queue_consumer(q):
        """Consume from an asyncio.Queue, making it an async iterable"""
        while True:
            try:
                e = await q.get()
                yield e
            except:
                continue

正在使用async for 拉出消费者。 在这种特殊情况下,从特定队列消费的协程顺序调用一些代码,将数据放入其队列中put_nowait 编辑:在这种特殊情况下,正在侦听入站网络流量的协程 A 将消息放入协程 B 的队列中。

我注意到在协程 A 中对 put_nowait 的调用之间存在一致的 ~50ms 延迟,然后由于从协程 B 中的可迭代队列中拉取数据而正在处理的数据.

我怀疑它可能与某些 asyncio 内部轮询解决方案有关,但我不确定,我不会怀疑这种配置可以在哪里修改。

我对增加异步loop 中的事件轮询频率非常感兴趣,因此可以减少put_nowaitget 与协程之间的队列之间观察到的延迟。也许还有一种方法可以提示 asyncio 框架更早地处理队列中的项目?

注意:我正在使用的应用程序没有执行任何计算要求高的工作。

【问题讨论】:

  • put_nowait 和下一个 await 之间会发生什么,实际上返回到事件循环?
  • @dirn 我已经更正了问题规范。你的问题还有效吗?
  • 你能用我们可以运行的最小示例重现这个吗?例如。只需启动两个协程,在适当的位置打印time.time(),等等。
  • 是的,我的问题仍然有效。除非put_nowait 之后的下一行代码将控制权交还给循环(例如,await asyncio.sleep(0)),否则从队列中拉出的协程可能在这 50 毫秒的大部分时间里都没有机会检查它。
  • @dirn 原来问题很简单,而且很尴尬。不过,由于这一点,我对 asyncio 有了更多的了解。详情请看我的回答。

标签: queue python-3.6 python-asyncio event-loop


【解决方案1】:

原来问题是由于我的应用使用prompt_toolkit 进行了一些 UI 更新引起的。我通过在_run_once 中放置一些测量值来追踪这一点。无论如何,队列没有被处理,因为事件循环正忙于执行一些我没想到会花费这么多时间的 UI 代码。

【讨论】:

    猜你喜欢
    • 2019-10-23
    • 2017-07-31
    • 1970-01-01
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多