1

計算を行い、計算の状態をresult辞書に保存する関数があります(デフォルトのデフォルト引数)。最初に実行し、次にマルチプロセッシングモジュールを使用していくつかのプロセスを実行します。これらの各並列プロセスで関数を再度実行する必要がありますが、この関数を1回実行した後、キャッシュされた状態を返す必要があります。値を再計算しないでください。この要件は私の例では意味がありませんが、この制限を必要とする単純で現実的な議論を考えることはできません。変更可能なデフォルト引数としてdictを使用することは機能しますが、これはマルチプロセッシングモジュールでは機能しません。同じ効果を得るためにどのようなアプローチを使用できますか?

状態値は、引数afaikとして複数のプロセスに渡すことができないもの(クラス値を含むディクショナリ)であることに注意してください。

SOの質問Pythonマルチプロセッシング:複数のプロセス間でdictを共有するにはどうすればよいですか?同様の地面をカバーしているようです。おそらく、マネージャーを使用して必要なことを実行できますが、その方法は明らかではありません。あるいは、https://stackoverflow.com/a/4534956/350713に従って、値をグローバルオブジェクトに保存することもできますが、それはあまりエレガントではないようです。

def foo(result={}):
    if result:
        print "returning cached result"
        return result
    result[1] = 2
    return result

def parafn():
    from multiprocessing import Pool
    pool = Pool(processes=2)
    arglist = []
    foo()
    for i in range(4):
        arglist.append({})
    results = []
    r = pool.map_async(foo, arglist, callback=results.append)
    r.get()
    r.wait()
    pool.close()
    pool.join()
    return results

print parafn()

更新:コメントありがとうございます。私は今、以下に投稿された実用的な例を持っています。

4

2 に答える 2

1

このコードは美容賞を獲得することはありませんが、私にとってはうまくいきます。この例は、質問の例と似ていますが、いくつかの小さな変更があります。構成は少し厄介ですが、これadd_to_dを行うためのより良い方法はわかりません。

簡単な要約:foo'sの状態d(可変のデフォルト引数)をにコピーして戻しますfoofoo、プールによって作成された新しいプロセススペースにあります。これが行わfooれると、新しいプロセススペースではキャッシュされた値が再計算されません。ドキュメントはあまり明確ではありませんが、これはプール初期化子が行うことのようです。

class bar(object):
    def __init__(self, x):
        self.x = x
    def __repr__(self):
        return "<bar "+ str(self.x) +">"

def foo(x=None, add_to_d=None, d = {}):
    if add_to_d:
        d.update(add_to_d)
    if x is None:
        return
    if x in d:
        print "returning cached result, d is %s, x is %s"%(d, x)
        return d[x]
    d[x] = bar(x)
    return d[x]

def finit(cacheval):
    foo(x=None, add_to_d=cacheval)

def parafn():
    from multiprocessing import Pool
    arglist = []
    foo(1)
    pool = Pool(processes=2, initializer=finit, initargs=[foo.func_defaults[2]])
    arglist = range(4)
    results = []
    r = pool.map_async(foo, iterable=arglist, callback=results.append)
    r.get()
    r.wait()
    pool.close()
    pool.join()
    return results

print parafn()
于 2012-10-02T04:29:51.593 に答える
1

プロセス間でデータを交換する最も安全な方法はキューを使用することだと思います。マルチプロセッシングモジュールは、キューとJoinableQueueの2種類を提供します。ドキュメントを参照してください。

http://docs.python.org/library/multiprocessing.html#exchanging-objects-between-processes

于 2012-09-30T17:06:53.833 に答える