如何对Python线程进行限速?

7
我有一个线程在进行大量的CPU密集型处理,似乎阻塞了其他线程。我该如何限制它?
这是针对web2py的特定情况,但通用的解决方案也可以。

3
一个线程需要多少CPU资源是不太可能导致其阻塞。更有可能的情况是你遇到了全局解释器锁的问题(http://wiki.python.org/moin/GlobalInterpreterLock)。你需要提供更多信息以帮助我们评估情况。你的线程究竟在做什么? - Wilduck
1
@Wilduck,CPU 密集型线程可能会增加 IO 延迟(尽管在最近的 Python 中减少了),请参见此处以进行说明:http://dabeaz.blogspot.com/2010/01/python-gil-visualized.html - Tobu
@Wilduck 这个线程实际上调用了 JS 代码。我很想尝试释放 GIL(如果还没有被释放),但这会迫使我确保 JS 在任何时候都不需要 GIL... 我可能会暂时将其保留,并找到一个解决方法。 - Chris
2个回答

4

我不久前刚刚深入研究了这个问题,你无法改变线程的优先级,但有些方法可以解决这个问题。

为了让你更好地理解问题的背景,cPython实现中的CPU绑定线程会因全局解释器锁(GIL)的释放和获取方式而导致其他线程饿死。奇怪的是,在多核环境下,这个问题会更加严重。 David Beazley 对这个问题进行了详细的分析和演示,你可以在 http://www.dabeaz.com/python/GIL.pdf 上找到他的文章。他还有一些更详细的博客文章,虽然很长,但非常有趣。

简单来说,CPU绑定线程在其他线程被唤醒之前释放并重新获取GIL,导致CPU绑定线程持有GIL超过90%的时间。

有一些模式可以用来解决这个问题。例如,你可以在完全不同的进程中运行CPU绑定任务。这将允许操作系统调度程序更好地管理资源共享,并应该允许您的web2py线程继续运行,因为操作系统实际上会给予IO绑定线程优先处理。为此,提供了multiprocessing库。它需要一些额外的代码才能工作,但应该有所帮助。


多进程看起来是一个可能的选项,谢谢@William-- - Chris

1
你正在使用哪个版本的Python? 在3.2中,GIL被更改为在固定时间片后产生,而不是在一定数量的高级操作码之后产生。
即使有了这个变化,运行CPU密集型代码仍然会影响您的Web应用程序的延迟(反之,IO敏感部分将防止CPU密集部分占用整个核心)。 您应该使用像beanstalkd这样的队列将任务分派给工作进程,并让操作系统调度程序自行处理。

我认为新的GIL只在3.2版本中存在。他们实际上正在3.3版本中进一步改进它http://bugs.python.org/issue7946。不幸的是,网络框架中对Python 3的支持才刚刚开始。我还没有听说过一个稳定的网络框架。 - William
@William 谢谢,已经更正。勇敢的人们可以在此处找到一个回溯。 - Tobu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接