我有一个用python编写的系统,它使用由不同开发人员编写的插件处理大量数据。
基本上,应用程序启动多个工作线程,然后为它们提供数据。每个线程确定用于项目的插件并要求它处理该项目。插件只是一个定义了特定功能的python模块。处理通常涉及正则表达式,不应超过一秒左右。
有时,其中一个插件需要分钟才能完成,将CPU固定在100%的整个时间。这通常是由次优正则表达式与暴露效率低下的数据项配对引起的。
这是事情变得棘手的地方。如果我怀疑罪魁祸首是谁,我可以检查它的代码并找到问题所在。但是,有时我不是那么幸运。
没有将整个架构重写为多处理,我可以通过任何方式找出谁在吃掉我所有的CPU?
ADDED :回答一些评论:
在python中分析多线程代码没有用,因为分析器测量的是总函数时间而不是活动的cpu时间。试试cProfile.run('time.sleep(3)')看看我的意思。 (信用rog [最后评论])。
单线程变得棘手的原因是因为20,000中只有1项导致问题,我不知道它是哪一个。运行多线程允许我在大约一个小时内完成20,000个项目,而单线程可能需要更长的时间(涉及很多网络延迟)。还有一些我现在不想进入的并发症。
也就是说,尝试序列化调用插件的特定代码并不是一个坏主意,因此一个的时序不会影响其他的时序。我会尝试并报告回来。
答案 0 :(得分:3)
你显然不需要多线程,只需要并发,因为你的线程不共享任何状态:
尝试多处理而不是多线程
单线程/ N子进程。 在那里你可以为每个请求计时,因为没有GIL被保留。
其他可能性是摆脱多个执行线程并使用基于事件的网络编程(即使用扭曲)
答案 1 :(得分:0)
正如你所说,由于GIL,在同一个过程中是不可能的。
我建议启动第二个监视进程,该进程侦听原始应用程序中另一个线程的生命节拍。一旦指定的时间内缺少该时间节拍,监视器可以终止您的应用并重新启动它。
答案 2 :(得分:0)
如果建议您可以控制框架禁用除一个插件之外的所有插件并查看。 基本上如果你有P1,P2 ...... Pn插件 运行N进程并先禁用P1,然后禁用P2,依此类推
与多线程运行相比,它会快得多,因为没有GIL阻塞,你会很快知道哪个插件是罪魁祸首。
答案 3 :(得分:0)
我仍然会看看nosklo的建议。您可以在单个线程上进行概要分析以找到该项目,并在您的长期运行中获得转储可能会看到罪魁祸首。是的,我知道这是20,000件物品并且需要很长时间,但有时你只需要吸吮它并找到一个令人信服的事情来说服自己这个问题被抓住并照顾好了。运行脚本,然后开展其他建设性的工作。回来分析结果。这有时将男人和男孩分开; - )
或者/并且,添加记录信息,跟踪从每个插件处理每个项目时执行的时间。查看正在运行的程序结束时的日志数据,看看与其他程序相比,哪一个运行了很长时间。