10

これ (非常に単純化された例) は正常に動作します (Python 2.6.6、Debian Squeeze):

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()

しかし、もちろんそれは機能しません (何かをピクルすることができずにハングアップします)。

ここの例は些細なことですが、複数の「プロセス」関数を追加すると、それらのそれぞれが複数の追加入力に依存します...まあ、30 年前に BASIC で書かれたものを少し思い出させるものになります。クラスを使用して、少なくとも適切な関数で状態を集約しようとすることは明らかな解決策のように思えますが、実際にはそれほど簡単ではないようです

multiprocessing.pool を使用するための推奨されるパターンまたはスタイルはありますか?

経験豊富な「マルチプロセッシングのプロ」はこれにどのように対処しますか?

更新:私は実際にははるかに大きな配列の処理に興味があることに注意してください。そのため、src各呼び出し/反復をピクルする上記のバリエーションは、プールのワーカープロセスにフォークするものほど良くありません。

4

1 に答える 1

8

このような呼び出し可能なオブジェクトをいつでも渡すことができ、そのオブジェクトには共有状態を含めることができます。

from multiprocessing import Pool
import numpy as np

class RowProcessor(object):
    def __init__(self, src):
        self.__src = src
    def __call__(self, row):
        return np.sum(self.__src[row])

def main():
    src=np.ones((100,100))
    p = RowProcessor(src)

    pool=Pool(processes=16)
    rows = pool.map(p, range(100))
    print rows

if __name__ == "__main__":
    main()
于 2012-04-14T09:44:20.510 に答える