经过大量的研究和测试后,我发现“经理”在非复杂的对象级别执行此项工作。
下面所示inst
在进程之间共享该对象的代码,这意味着属性的inst
var
当子进程改变其外部改变。
from multiprocessing import Process, Manager
from multiprocessing.managers import BaseManager
class SimpleClass(object):
def __init__(self):
self.var = 0
def set(self, value):
self.var = value
def get(self):
return self.var
def change_obj_value(obj):
obj.set(100)
if __name__ == '__main__':
BaseManager.register('SimpleClass', SimpleClass)
manager = BaseManager()
manager.start()
inst = manager.SimpleClass()
p = Process(target=change_obj_value, args=[inst])
p.start()
p.join()
print inst # <__main__.SimpleClass object at 0x10cf82350>
print inst.get() # 100
好了,上面的代码是足够如果你只需要共享简单对象。
为什么不复杂吗?由于如果你的对象是嵌套(内部目标对象),它可能会失败:
from multiprocessing import Process, Manager
from multiprocessing.managers import BaseManager
class GetSetter(object):
def __init__(self):
self.var = None
def set(self, value):
self.var = value
def get(self):
return self.var
class ChildClass(GetSetter):
pass
class ParentClass(GetSetter):
def __init__(self):
self.child = ChildClass()
GetSetter.__init__(self)
def getChild(self):
return self.child
def change_obj_value(obj):
obj.set(100)
obj.getChild().set(100)
if __name__ == '__main__':
BaseManager.register('ParentClass', ParentClass)
manager = BaseManager()
manager.start()
inst2 = manager.ParentClass()
p2 = Process(target=change_obj_value, args=[inst2])
p2.start()
p2.join()
print inst2 # <__main__.ParentClass object at 0x10cf82350>
print inst2.getChild() # <__main__.ChildClass object at 0x10cf6dc50>
print inst2.get() # 100
#good!
print inst2.getChild().get() # None
#bad! you need to register child class too but there's almost no way to do it
#even if you did register child class, you may get PicklingError :)
我觉得这种行为的主要原因是因为Manager
只是一个直板建立在像管道低级别的通信工具之上/队列。
因此,这种做法是不以及建议多处理情况。它总是更好,如果你可以使用低级别的工具,如锁/信号灯/管材/队列或高层次的工具,如Redis的队列或Redis的发布/订阅复杂的使用情况下(只是我的建议笑)。
来源
2016-09-28 09:07:27
Tom
相关:http://stackoverflow.com/questions/659865/python-multiprocessing-sharing-a-large-read-only-object-between-processes – tokland 2010-09-08 21:18:50