2012-04-17 30 views
1

我试图在Python中同时运行两个长时间运行的操作。它们都在相同的数据集上运行,但不要修改它们。我发现一个线程实现运行速度比一个接一个地运行它们要慢。在Python中对可串行化操作进行线程化处理比按顺序执行它们要慢

我创建了一个简化的示例来展示我正在经历的事情。

运行此代码并注释第46行(导致它执行线程操作)会导致我的计算机上的运行时间约为1:01(分钟:秒)。我看到两个CPU在整个运行时间运行约50%。

注释掉第47行(导致顺序计算)将导致大约35秒的运行时间,其中1个CPU在整个运行时间内被固定为100%。
两次运行都会导致完整的计算完成。

from datetime import datetime 
import threading 


class num: 
    def __init__(self): 
     self._num = 0 

    def increment(self): 
     self._num += 1 

    def getValue(self): 
     return self._num 

class incrementNumber(threading.Thread): 
    def __init__(self, number): 
     self._number = number 
     threading.Thread.__init__(self) 

    def run(self): 
     self.incrementProcess() 

    def incrementProcess(self): 
     for i in range(50000000): 
      self._number.increment() 


def runThreaded(x, y): 
    x.start() 
    y.start() 
    x.join() 
    y.join() 

def runNonThreaded(x, y): 
    x.incrementProcess() 
    y.incrementProcess() 

def main(): 
    t = datetime.now() 

    x = num() 
    y = num() 
    incrementX = incrementNumber(x) 
    incrementY = incrementNumber(y) 

    runThreaded(incrementX, incrementY) 
    #runNonThreaded(incrementX, incrementY) 


    print x.getValue(), y.getValue() 
    print datetime.now() - t 


if __name__=="__main__": 
    main() 

回答

4

CPython中有一个所谓的Global Interpreter Lock,这意味着多线程时,只有一个Python的语句可以同时运行,甚至。你可能想看看multiprocessing,这可以避免这个限制。

GIL意味着Python多线程只能用于I/O绑定操作,等待事件发生的其他事情,或者如果您正在调用在工作时释放GIL的C扩展。

+0

反正我不使用Python,但我不明白为什么那个可怜的互斥体是必须的。难道Python不会在线程本地存储中存储上下文对象或指针吗?为每个线程找到其他自己的解释器实例的其他方法? – 2012-04-17 17:50:56

+0

从下面重复自己:有[Python的实现](http://wiki.python.org/jython/WhyJython)没有GIL。至于“每个线程都有自己的解释器实例” - 这就是“多处理”(答案中提到的)所做的。 – 2012-04-17 17:52:49

+0

有些开发人员不想与其他进程共享5GB数据缓冲区!就像你说的那样,Anywy似乎确实存在GILless pythons,所以我的回答是误导性的,即使不是错的。 – 2012-04-17 18:06:39

-2

Python在多线程中是垃圾。 Google for'GIL'

+3

我想你在这里的意思是“* CPython *在多线程中是垃圾” - 没有GIL的[Python的实现](http://wiki.python.org/jython/WhyJython)。即使使用CPython,也有解决方法(如[multiprocessing''](http://docs.python.org/library/multiprocessing.html#introduction))。 – 2012-04-17 17:49:53

+0

好的,是的,当然,显然你可以使用一个独立的进程,以及进程间通信和inter-thred通信所需要的全部内容 2012-04-17 18:04:02

+0

看起来在野外有GILless pythons,所以我的回答是,err ...'与真相经济' – 2012-04-17 18:07:38