web-dev-qa-db-ja.com

Pythonマルチプロセッシングプール、参加;続行するのを待っていませんか?

(1)_pool.map_に続いてpool.join()を使用しようとしていますが、pythonは_pool.map_が終了するのを待っていないようですpool.join()を通過する前に、私が試したことの簡単な例を示します。

_from multiprocessing import Pool

foo = {1: []}

def f(x):
    foo[1].append(x)
    print foo

def main():
    pool = Pool()
    pool.map(f, range(100))
    pool.close()
    pool.join()
    print foo

if __name__ == '__main__':
    main()
_

pythonはjoinコマンドを無視し、fを実行する前に_{1: []}_を実行したかのように、印刷出力は_print foo_です。意図した結果はfooです。が_{1:[0,1,...,99]}_であり、通常の組み込みpython mapを使用すると、この結果が得られます。プールされたバージョンが_{1: []}_を印刷するのはなぜですか。意図した結果を印刷しますか?

(2)理想的には、main()fooをローカル変数として定義し、fに渡しますが、foofの最初の引数にして、

pool.map(functools.partial(f, foo), range(100))

同じ出力を生成します。 (そして、おそらく各プロセスがfooの独自のコピーを持っているという問題もあります?)繰り返しますが、代わりに通常のmapを使用して動作します。

17
panavia

これはmapを使用する正しい方法ではありません。

  1. そのようにグローバル変数を使用することは絶対に間違っています。プロセスは(通常)同じメモリを共有しないため、すべてのfにはfooの独自のコピーがあります。異なるプロセス間で変数を共有するには、Managerを使用する必要があります
  2. mapに渡される関数は、通常、値を返すことが期待されています。

ドキュメント を読むことをお勧めします。

ただし、これを実装する方法のダミーの例を次に示します。

_from multiprocessing import Pool

foo = {1: []}

def f(x):
    return x

def main():
    pool = Pool()
    foo[1] = pool.map(f, range(100))
    pool.close()
    pool.join()
    print foo

if __name__ == '__main__':
    main()
_

また、fooManagerであるpool.map(functools.partial(f, foo), range(100))のようなこともできます。

25
smeso