2012-03-03 37 views
5

我有一个线程做了大量的CPU密集型处理,这似乎阻止了其他线程。我如何限制它?如何调节Python线程?

这是专门针对web2py的,但一般的解决方案应该没问题。

+3

线程的密集程度不太可能导致它被阻塞。更有可能的是,您遇到了Global Interpreter Lock(http://wiki.python.org/moin/GlobalInterpreterLock)的问题。您需要为我们提供更多信息来评估情况。你的线程究竟在干什么? – Wilduck 2012-03-03 00:16:11

+1

@Wilduck CPU密集型线程可能会增加IO延迟(尽管在最近的Python中没有这么做),请参阅以下内容:http://dabeaz.blogspot.com/2010/01/python-gil-visualized.html – Tobu 2012-03-03 11:18:12

+0

@Wilduck该线程实际上在JS中调用代码。我很想尝试释放GIL(如果它还没有的话),但这会迫使我确保JS在任何时候都不需要GIL ......我可能会暂时放弃它并找到解决方法。 – Chris 2012-03-05 18:00:52

回答

3

我刚刚结束了不久前潜入这个问题,你不能改变线程优先级,但有办法解决这个问题。

为了给你一点关于这个问题的背景知识,在cPython实现中,由于全局解释器锁或GIL被释放和获取的方式,CPU绑定线程可能导致其他线程挨饿。奇怪的是,这个问题在多核环境下变得更糟。关于这个问题的详细分析和介绍是由David Beazley完成的,你可以在http://www.dabeaz.com/python/GIL.pdf找到。他有几个更详细的博客文章。他们很长,但相当迷人。

简短版本是CPU绑定线程在其他线程被唤醒之前释放并重新获取GIL来获取它。 90%以上的时间导致CPU绑定线程持有GIL。

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

+0

多处理看起来像一个可能的选择,谢谢@ William-- – Chris 2012-03-05 17:57:25

1

您使用的是哪个版本的Python?在3.2中,the GIL was changed to yield after fixed timeslices rather than after a certain number of high-level opcodes

即使发生这种变化,运行CPU密集型代码也会影响Web应用程序的延迟(相反,IO敏感部分会阻止CPU密集型部分占用整个内核)。您应该使用像beanstalkd这样的队列将任务分离到工作进程,并让OS调度程序完成它的工作。

+0

我认为新的GIL只有3.2。他们实际上正在努力在3.3中进一步改进它http://bugs.python.org/issue7946不幸的是,在web框架中的python 3支持只是刚刚开始工作。我还没有听说过一个稳定的。 – William 2012-03-03 17:40:34

+0

@威廉谢谢,纠正。 [无畏的灵魂会在这里找到一个backport。](http://bugs.python.org/issue7753) – Tobu 2012-03-03 17:54:27