Python多进程中函数内修改对象属性不生效问题
问题原因
- 你用
multiprocessing.Manager()创建的manager.list本身是进程间共享的代理对象,但里面存放的abc类实例是普通Python对象,并非Manager管理的代理对象。 - 当子进程通过
b1[0]获取这个实例时,实际上得到的是原对象的深拷贝,子进程内对test.a的修改只作用于这个副本,不会同步到父进程的原a1对象。
解决方案
下面提供几种可行的解决方式:
方法1:使用Manager.Namespace包装自定义对象
Namespace可以创建一个可共享的代理对象,用来存放自定义类的属性:
import multiprocessing class abc(): def __init__(self): self.a = [1,2] self.b = [1,2,3] def one(test): a = len(test.a) + 1 test.a.append(a) print('test.a==', test.a) if __name__ == '__main__': with multiprocessing.Manager() as manager: # 用Namespace包装abc实例 a1_proxy = manager.Namespace() a1_proxy.obj = abc() a2_proxy = manager.Namespace() a2_proxy.obj = abc() p1 = multiprocessing.Process(target=one, args=[a1_proxy.obj]) p2 = multiprocessing.Process(target=one, args=[a2_proxy.obj]) p1.start() p2.start() p1.join() p2.join() print(a1_proxy.obj.a) # 输出 [1,2,3]
方法2:让自定义类成为可代理类型
通过注册自定义类到BaseManager,让Manager可以创建该类的代理对象:
import multiprocessing from multiprocessing.managers import BaseManager class abc(): def __init__(self): self.a = [1,2] self.b = [1,2,3] # 注册自定义类到BaseManager BaseManager.register('abc', abc) def one(test): a = len(test.a) + 1 test.a.append(a) print('test.a==', test.a) if __name__ == '__main__': with BaseManager() as manager: # 创建代理对象 a1 = manager.abc() a2 = manager.abc() p1 = multiprocessing.Process(target=one, args=[a1]) p2 = multiprocessing.Process(target=one, args=[a2]) p1.start() p2.start() p1.join() p2.join() print(a1.a) # 输出 [1,2,3]
方法3:直接使用共享列表替代实例属性
如果需求简单,也可以直接用manager.list()作为实例的a属性,这样属性本身就是共享代理:
import multiprocessing class abc(): def __init__(self, manager): # 用manager创建共享列表 self.a = manager.list([1,2]) self.b = manager.list([1,2,3]) def one(test): a = len(test.a) + 1 test.a.append(a) print('test.a==', test.a) if __name__ == '__main__': with multiprocessing.Manager() as manager: a1 = abc(manager) a2 = abc(manager) p1 = multiprocessing.Process(target=one, args=[a1]) p2 = multiprocessing.Process(target=one, args=[a2]) p1.start() p2.start() p1.join() p2.join() print(list(a1.a)) # 输出 [1,2,3]
内容的提问来源于stack exchange,提问作者Ragavan Selva
相关产品推荐
相关产品推荐

