10

実験と学習だけで、複数のプロセスでアクセスできる共有辞書を作成する方法は知っていますが、辞書を同期させる方法はわかりません。defaultdict、私が抱えている問題を示していると思います。

from collections import defaultdict
from multiprocessing import Pool, Manager, Process

#test without multiprocessing
s = 'mississippi'
d = defaultdict(int)
for k in s:
    d[k] += 1

print d.items() # Success! result: [('i', 4), ('p', 2), ('s', 4), ('m', 1)]
print '*'*10, ' with multiprocessing ', '*'*10

def test(k, multi_dict):
    multi_dict[k] += 1

if __name__ == '__main__':
    pool = Pool(processes=4)
    mgr = Manager()
    multi_d = mgr.dict()
    for k in s:
        pool.apply_async(test, (k, multi_d))

    # Mark pool as closed -- no more tasks can be added.
    pool.close()

    # Wait for tasks to exit
    pool.join()

    # Output results
    print multi_d.items()  #FAIL

print '*'*10, ' with multiprocessing and process module like on python site example', '*'*10
def test2(k, multi_dict2):
    multi_dict2[k] += 1


if __name__ == '__main__':
    manager = Manager()

    multi_d2 = manager.dict()
    for k in s:
        p = Process(target=test2, args=(k, multi_d2))
    p.start()
    p.join()

    print multi_d2 #FAIL

最初の結果は ( を使用していないためmultiprocessing) 動作しますが、 で動作させるのに問題がありmultiprocessingます。解決方法はわかりませんが、同期されていない(そして後で結果に参加する)か、辞書multiprocessingに設定する方法がわからないことが原因である可能性があります。defaultdict(int)

これを機能させる方法に関するヘルプや提案は素晴らしいでしょう!

4

2 に答える 2

16

共有する追加の型をサブクラス化BaseManagerして登録できます。AutoProxyで生成されたデフォルトのタイプが機能しない場合は、適切なプロキシ タイプを指定する必要があります。defaultdictに既に存在するアトリビュートにのみアクセスする必要がある場合は、dictを使用できますDictProxy

from multiprocessing import Pool
from multiprocessing.managers import BaseManager, DictProxy
from collections import defaultdict

class MyManager(BaseManager):
    pass

MyManager.register('defaultdict', defaultdict, DictProxy)

def test(k, multi_dict):
    multi_dict[k] += 1

if __name__ == '__main__':
    pool = Pool(processes=4)
    mgr = MyManager()
    mgr.start()
    multi_d = mgr.defaultdict(int)
    for k in 'mississippi':
        pool.apply_async(test, (k, multi_d))
    pool.close()
    pool.join()
    print multi_d.items()
于 2012-02-13T09:31:35.890 に答える
3

まあ、Managerクラスは、プロセス間で共有できる定義済みのデータ構造の固定数のみを提供するように見えますが、defaultdictそれらの間ではありません。本当にそれが必要な場合defaultdict、最も簡単な解決策は、デフォルトの動作を独自に実装することです。

def test(k, multi_dict):
    if k not in multi_dict:
        multi_dict[k] = 0
    multi_dict[k] += 1
于 2012-02-13T08:04:07.833 に答える