监视asyncio事件循环

Mar*_*ane 9 profiler python-3.x python-asyncio

我正在使用python3编写应用程序,并且我第一次尝试使用asyncio.我遇到的一个问题是我的一些协程阻止事件循环的时间比我想要的长.我试图在事件循环的顶部找到一些东西,它将显示运行每个协同程序所花费的壁/ CPU时间.如果没有任何已经存在的东西有没有人知道一种方法来添加钩子到事件循环,以便我可以进行测量?

我尝试过使用cProfile,它提供了一些有用的输出,但我对阻塞事件循环的时间更感兴趣,而不是总执行时间.

Mik*_*mov 13

事件循环已经可以跟踪协同程序是否需要很多CPU时间来执行.要查看它,您应该使用方法启用调试模式set_debug:

import asyncio
import time


async def main():
    time.sleep(1)  # Block event loop


if __name__ == "__main__":
    loop = asyncio.get_event_loop()
    loop.set_debug(True)  # Enable debug
    loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)

在输出中你会看到:

Executing <Task finished coro=<main() [...]> took 1.016 seconds
Run Code Online (Sandbox Code Playgroud)

默认情况下,它会显示阻止超过0.1秒的协同程序的警告.它没有记录,但基于asyncio 源代码,看起来您可以更改slow_callback_duration属性以修改此值.


kwa*_*nek 6

你可以用call_later.定期运行回调,记录/通知循环时间和周期间隔时间的差异.

class EventLoopDelayMonitor:

    def __init__(self, loop=None, start=True, interval=1, logger=None):
        self._interval = interval
        self._log = logger or logging.getLogger(__name__)
        self._loop = loop or asyncio.get_event_loop()
        if start:
            self.start()

    def run(self):
        self._loop.call_later(self._interval, self._handler, self._loop.time())

    def _handler(self, start_time):
        latency = (self._loop.time() - start_time) - self._interval
        self._log.error('EventLoop delay %.4f', latency)
        if not self.is_stopped():
            self.run()

    def is_stopped(self):
        return self._stopped

    def start(self):
        self._stopped = False
        self.run()

    def stop(self):
        self._stopped = True
Run Code Online (Sandbox Code Playgroud)

import time

async def main():
    EventLoopDelayMonitor(interval=1)
    await asyncio.sleep(1)
    time.sleep(2)
    await asyncio.sleep(1)
    await asyncio.sleep(1)

loop = asyncio.get_event_loop()
loop.run_until_complete(main())
Run Code Online (Sandbox Code Playgroud)

产量

EventLoop delay 0.0013
EventLoop delay 1.0026
EventLoop delay 0.0014
EventLoop delay 0.0015
Run Code Online (Sandbox Code Playgroud)