程序在__init__和run方法之间挂起超过60秒?

时间:2013-10-12 18:12:32

标签: python multiprocessing

我遇到了一个奇怪的问题。 据我所知,将数据分配给变量的实际行为导致我的程序出现大量延迟。我测量了实际构建我想要分配给实例变量的数据所花费的时间,并且它平均大约为.7秒。只有当我尝试分配它(例如self.data = data)时才会发生大规模延迟。

编辑:

上述假设不正确。在变量赋值期间,挂起。我在调用build_data之前和之后添加了一个计时器,时间可以忽略不计。

延迟是在__init__完成和调用run之间的某种程度上。

更新了班级

这是该课程的代码。我添加了一个计时器,它从__init__结束时开始,并在第一次调用run()时停止。两者之间有50秒的延迟!

class Worker(multiprocessing.Process):
    def __init__(self, queue, image): 
        multiprocessing.Process.__init__(self)
        self.queue = queue
        self.data = self.build_data(image)
            self.start_time = time.time()

    def run(self): 
        print 'I finally reached the run statement!'
        print "Time taken:", time.time() - self.start_time
        print "Exiting {}".format(self.name)

build_data功能。

        def build_data(self, im): 
            start_time = time.time()
            size, data = im.size, list(im.getdata())
            data = [data[x:size[0] + x] for x in range(0, len(data), size[0])]
            print 'Process time:', time.time() - start_time
            return data

任何人都知道造成这种情况的原因是什么?

工作人员代码:

if __name__ == '__main__':
    im = ImageGrab.grab()
    queue = multiprocessing.Queue()
    workers = [] 
    for i in range(1): 
        w = Worker(queue, im)
        w.start()
        workers.append(w)


    print 'waiting for workers to join'
    for i in workers: i.join()

部分解决方案:

在Toreks的建议中,我查看了multiprocessing上的编程指南,其中指出传递给__init__的所有参数都是可选的。我对内部的理解非常模糊,但我想代码中的延迟是巨大的嵌套列表结构被传递给__init__时被腌制/取消(尽管可能完全错误)。

将数据移出__init__,稍后再分配可以完全解决问题。没有更多的延迟。

工作代码:

class Worker(DataStore):
    data = None
    def __init__(self, queue, image): 
        multiprocessing.Process.__init__(self)
        self.queue = queue
        self.img = image
        self.start_time = time.time() 


    def run(self):
        self.assign_data(self.img)
        print 'I finally reached the run statement!'
        print "Time taken:", time.time() - self.start_time
        print "Exiting {}".format(self.name)


    @classmethod
    def assign_data(cls, im): 
        size, data = im.size, list(im.getdata())
        cls.data = [
            data[x:size[0] + x] for x in range(0, len(data), size[0])
        ]

所以,我只是将data变量移到了类范围,然后将build_data变成了@classmethod。现在一切都在游泳。

0 个答案:

没有答案