我有成千上万个异步任务正在运行。
某些需要消耗大量 CPU 时间的任务需要大约 10 秒才能完成。
这导致程序无法正常工作,因为有些任务需要在他们的网络连接中回复消息,比如说在 5 秒内。
我的当前想法是以某种方式拦截事件循环。 在 asyncio 模块中,必须有一些区域在每次 epoll() 或 select() 之间执行所有当前活动任务的事件循环中。如果我能在每个任务“恢复”之前插入“elapsed = time.time()”,然后在每个任务“恢复”之后插入“elapsed = time.time() - elapsed ”,我认为就足以找出花费太多时间的任务了。
我认为相关的代码可能在此处,位于第 79 行: https://github.com/python/cpython/blob/master/Lib/asyncio/events.py
def _run(self):
try:
self._context.run(self._callback, *self._args)
except (SystemExit, KeyboardInterrupt):
raise
except BaseException as exc:
cb = format_helpers._format_callback_source(
self._callback, self._args)
msg = f'Exception in callback {cb}'
context = {
'message': msg,
'exception': exc,
'handle': self,
}
if self._source_traceback:
context['source_traceback'] = self._source_traceback
self._loop.call_exception_handler(context)
self = None # Needed to break cycles when an exception occurs.
但我不知道在这里该怎么做才能打印出有用的信息。我需要一种方法来识别这个 "self._context.run (...)" 将执行哪一行我的代码。
我已经过去了最后5个不眠之夜试图修复我的代码,但没有成功。
我尝试使用CProfiler、line_profile,但它们都没有帮助。它们告诉我执行函数所需的时间以及每行所花费的时间。我需要找出的是在每次循环迭代之间代码所需的时间。
所有我尝试过的性能分析/调试工具都没有给我任何线索应该修复什么问题。即使我用不同的方式重写了相同的程序约15次,我仍然无法让它正常工作。
我只是一个非专业的程序员,还是 Python 的新手,但如果我不能解决这个问题,那么下一步就是学习Rust,这本身就会是一个巨大的痛苦,可能在我开始学习之后三年,我才能让它工作,而本应该只需要两个月的时间。