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