Несмотря на то, что вы инкапсулируете объект, многопроцессорный модуль в конечном итоге будет использовать локальную копию объекта в каждом процессе и никогда фактически не передаст вам ваши изменения. В этом случае вы неправильно используете 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'}
person
jdi
schedule
04.07.2012