奇妙な問題に遭遇しました。私が知る限り、データを変数に代入するという実際の行為は、私のプログラムに大きな遅延を引き起こしています。インスタンス変数に割り当てたいデータを実際に構築するのにかかる時間を測定したところ、平均で約 0.7 秒でした。self.data = data
大規模な遅延が発生するのは、割り当てようとしたときだけです(たとえば)。
編集:
上記の仮定は正しくありませんでした。変数の割り当て中にハングしていませんでした。への呼び出しの前後にタイマーを追加しましたbuild_data
が、時間はごくわずかです。
__init__
遅延は、終了しrun
て呼び出される間に何らかの形で発生します。
更新されたクラス
これがクラスのコードです。__init__
の最後に開始し、 の最初の呼び出しで停止するタイマーを追加しましたrun()
。2 つの間に 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
渡されるすべての引数が pickle 化可能であると述べているのプログラミング ガイドラインに目を通しました__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
. すべてがスムーズに動作するようになりました。