プログラムは次のとおりです。
#!/usr/bin/python
import multiprocessing
def dummy_func(r):
pass
def worker():
pass
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=16)
for index in range(0,100000):
pool.apply_async(worker, callback=dummy_func)
# clean up
pool.close()
pool.join()
メモリ使用量 (VIRT と RES の両方) が close()/join() まで増加し続けていることがわかりました。これを取り除く解決策はありますか? 2.7 で maxtasksperchild を試しましたが、どちらも役に立ちませんでした。
apply_async() を ~6M 回呼び出すより複雑なプログラムがあり、~1.5M の時点で既に 6G+ RES を取得しています。他のすべての要因を回避するために、プログラムを上記のバージョンに単純化しました。
編集:
みんなの意見に感謝します。
#!/usr/bin/python
import multiprocessing
ready_list = []
def dummy_func(index):
global ready_list
ready_list.append(index)
def worker(index):
return index
if __name__ == '__main__':
pool = multiprocessing.Pool(processes=16)
result = {}
for index in range(0,1000000):
result[index] = (pool.apply_async(worker, (index,), callback=dummy_func))
for ready in ready_list:
result[ready].wait()
del result[ready]
ready_list = []
# clean up
pool.close()
pool.join()
メインプロセスはシングルスレッドであると信じているため、そこにロックを配置しませんでした(コールバックは、私が読んだドキュメントごとに多かれ少なかれイベント駆動型のものに似ています)。
v2 と同じように、v1 のインデックス範囲を 1,000,000 に変更し、いくつかのテストを行いました。v2 は v1 よりも最大 10% 高速です (33 秒と 37 秒)。v2 は間違いなくメモリ使用量の勝者です。300M (VIRT) と 50M (RES) を超えることはありませんでしたが、v1 は以前は 370M/120M で、最高は 330M/85M でした。すべての数値は 3 ~ 4 回のテストであり、参考値です。