经过大量的研究和测试,我发现“经理”在非复杂的对象层面上完成这项工作。
下面的代码显示了对象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>
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>
print inst2.getChild() # <__main__.childclass object at>
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发布/订阅等高级工具来处理复杂的用例(仅限我的推荐lol),那总是更好。