これは、(非常に簡略化した例)ファイン(Pythonの2.6.6、Debianのスクイズを)作品:グローバルな状態の拡散を避けるための、Pythonマルチプロセッシングの代替パターン?
from multiprocessing import Pool
import numpy as np
src=None
def process(row):
return np.sum(src[row])
def main():
global src
src=np.ones((100,100))
pool=Pool(processes=16)
rows=pool.map(process,range(100))
print rows
if __name__ == "__main__":
main()
しかし、悪いグローバル状態を教えられているの年後!
from multiprocessing import Pool
import numpy as np
def main():
src=np.ones((100,100))
def process(row):
return np.sum(src[row])
pool=Pool(processes=16)
rows=pool.map(process,range(100))
print rows
if __name__ == "__main__":
main()
が、動作しませんもちろんの(何かをpickle化することができませんでしハングアップ):、すべての私の本能は、私は本当にむしろに近い何かを書くことになる私に言っています。
ここでの例は簡単ですが、複数の「プロセス」関数を追加するときには、それぞれが複数の追加入力に依存しています...まあまあそれは30年前にBASICで書かれた何かを連想させるようになります。クラスを使用して少なくとも状態を適切な関数で集計しようとするのは明らかな解決策ですが、実際にはdoesn't seem to be that easyです。
multiprocessing.poolを使用するために推奨されるパターンやスタイルがありますが、パラレルマップしたい各機能をサポートするためにグローバルな状態が広がることはありませんか?
経験豊富な「マルチプロセッシングプロ」はこれにどのように対処していますか?
更新は:ピクルスsrc
上記各コール/反復の変動がどのプールのワーカープロセスにフォーク、それをものとほぼ同じ良いものではありませんので、私は、はるかに大きな配列を処理中に実際に興味があることに注意してください。
を単純にpool.map(process、product([src]、range(100)))を実行し、両方の変数をargsとして受け入れるようにプロセス関数を変更しますか?これは非常に非効率的ですか? – luke14free
@ luke14free:はい、それはすべての呼び出しのためのsrc配列をpickleしていました。私は実際には、上記のサンプルコードよりもはるかに大きなデータ/配列に興味があります。プロセスプールでは、プールが作成された時点でどのような状態に設定されていても、ワーカープロセスにフォークされ、 "無償で"読むことができます。そのアイデアは、より小さなマイナーな「制御変数」(例えば、フラグ)状態をグローバルに置くことを避けるのに役立つだろう。 – timday