3

我遇到了一个奇怪的问题。据我所知,将数据分配给变量的实际行为会导致我的程序出现大量延迟。我测量了实际构建要分配给实例变量的数据所需的时间,平均约为 0.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. 现在一切正常。

4

0 回答 0