1

これが私によるものなのか、Python2.7のマルチプロセッシングモジュールによるものなのかわかりません。なぜこれが機能しないのか誰かが理解できますか?

from multiprocessing import pool as mp
class encapsulation:
   def __init__(self):
       self.member_dict = {}
   def update_dict(self,index,value):
       self.member_dict[index] = value
encaps = encapsulation()
def method(argument):
   encaps.update_dict(argument,argument)
   print encaps.member_dict
p = mp() #sets up multiprocess pool of processors
p.map(method,sys.argv[1:]) #method is the function, sys.argv is the list of arguments to multiprocess
print encaps.member_dict
>>>{argument:argument}
>>>{}

ですから、私の質問はメンバー変数についてです。クラスのカプセル化は、このディクショナリを関数の内外に保持する必要があることを理解しています。一度だけ初期化したのに、なぜリセットされて空の辞書が表示されるのですか?助けてください

4

1 に答える 1

2

オブジェクトをカプセル化していても、マルチプロセッシング モジュールは最終的に各プロセスでオブジェクトのローカル コピーを使用することになり、実際に変更をユーザーに伝達することはありません。この場合、Pool.map を適切に使用していません。各メソッド呼び出しが結果を返し、それが戻り値に送り返されることを期待しているためです。共有オブジェクトに影響を与えたい場合は、共有メモリを調整するマネージャーが必要です。

共有オブジェクトのカプセル化

from multiprocessing import Pool 
from multiprocessing import Manager
import sys

class encapsulation:
   def __init__(self):
       self.member_dict = {}
   def update_dict(self,index,value):
       self.member_dict[index] = value

encaps = encapsulation()

def method(argument):
   encaps.update_dict(argument,argument)
   # print encaps.member_dict       

manager = Manager()
encaps.member_dict = manager.dict()

p = Pool()
p.map(method,sys.argv[1:])

print encaps.member_dict

出力

$ python mp.py a b c
{'a': 'a', 'c': 'c', 'b': 'b'}

共有オブジェクトをメンバー属性として実際に設定するのではなく、引数として渡すか、共有オブジェクト自体をカプセル化してから、その値を dict に渡すことをお勧めします。共有オブジェクトを永続的に保持することはできません。空にして破棄する必要があります。

# copy the values to a reg dict
encaps.member_dict = encaps.member_dict.copy()

しかし、これはさらに良いかもしれません:

class encapsulation:
   def __init__(self):
       self.member_dict = {}
   # normal dict update
   def update_dict(self,d):
       self.member_dict.update(d)

encaps = encapsulation()

manager = Manager()
results_dict = manager.dict()

# pass in the shared object only
def method(argument):
   results_dict[argument] = argument    

p = Pool()
p.map(method,sys.argv[1:])

encaps.update_dict(results_dict)

意図したとおりに pool.map を使用する

マップを使用して値を返す場合、次のようになります。

def method(argument):
   encaps.update_dict(argument,argument)
   return encaps.member_dict

p = Pool()
results = p.map(method,sys.argv[1:]) 
print results
# [{'a': 'a'}, {'b': 'b'}, {'c': 'c'}]

結果を dict に再度結合する必要があります。

for result in results:
    encaps.member_dict.update(result)
print encaps.member_dict
# {'a': 'a', 'c': 'c', 'b': 'b'}
于 2012-07-04T01:46:04.717 に答える