Python - 多进程,类的成员函数

标签 python class multiprocessing encapsulation

我不知道这是我的原因,还是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}
>>>{}

所以我的问题只是关于成员变量。据我了解,类封装应该在函数内部和外部保存这个字典。为什么它会重置并给我一个空字典,即使我只初始化了一次?请帮忙

最佳答案

即使您封装了该对象,多处理模块最终也会在每个进程中使用该对象的本地副本,并且永远不会真正将您的更改传播回给您。在这种情况下,您没有正确使用 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'}

我建议不要真正将共享对象设置为成员属性,而是作为参数传递,或者封装共享对象本身,然后将其值传递到您的字典中。共享对象不能持久保留。需要清空并丢弃:

# 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'}]

您需要再次将结果合并到您的字典中:

for result in results:
    encaps.member_dict.update(result)
print encaps.member_dict
# {'a': 'a', 'c': 'c', 'b': 'b'}

关于Python - 多进程,类的成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11321370/

相关文章:

python - 将 yaml 配置文件传递给 Essentia MusicExtractor 时出现运行时错误

Java,堆叠类

python - python-3.5 中死多处理的未知原因

python - 使用多处理时实例属性不会持续存在

python - 使用附加条件合并两个数据框

c++ - 从输入中添加连续整数(从 Python 翻译成 C++)

python - 如何使用来自 Factory_boy 的 Faker

c++ - 类/成员函数错误

php - 创建了多少个类的实例

python - 无法使用 python 的多处理 Pool.apply_async() 腌制 <type 'instancemethod'>