Python多进程中类属性丢失问题咨询
Python多进程修改对象属性后列表仍为空的原因及解决方法
问题根源
Python多进程的核心机制是进程间内存完全隔离:每个子进程启动时会复制父进程的内存数据(类实例、变量等),你在worker_func里修改的对象只是子进程中的副本,父进程里的原对象根本不会被改动,所以最终打印的还是初始状态的空列表。
另外你原代码里每次循环都创建新的Pool,这属于不必要的性能浪费,后续解决方法会一并优化。
解决方法
方法1:返回修改后的对象,父进程替换原实例
让工作函数把修改后的对象返回给父进程,父进程用返回的实例替换原列表中的对象,这样就能同步修改结果:
修改后的完整代码:
from multiprocessing import Pool import random class my_class: def __init__(self, id): self.id = id self.awesome_list = [] def update_list(self): self.awesome_list.append(random.randint(0,9)) def worker_func(obj): obj.update_list() return obj # 返回修改后的对象 def main(): my_objs = [my_class(1), my_class(2)] # 只创建一次进程池,避免重复开销 with Pool() as pool: for _ in range(10): # 接收子进程返回的对象,替换原列表 my_objs = pool.starmap(worker_func, zip(my_objs)) # 查看结果 for ob in my_objs: print(ob.id) print(ob.awesome_list) if __name__ == '__main__': main()
方法2:使用Manager创建可共享列表
如果不想每次替换对象,可以用multiprocessing.Manager创建进程间共享的列表,这样所有子进程修改的都是同一个共享列表,父进程能直接看到结果:
修改后的完整代码:
from multiprocessing import Pool, Manager import random class my_class: def __init__(self, id, manager): self.id = id # 使用Manager创建可共享列表 self.awesome_list = manager.list() def update_list(self): self.awesome_list.append(random.randint(0,9)) def worker_func(obj): obj.update_list() def main(): manager = Manager() my_objs = [my_class(1, manager), my_class(2, manager)] with Pool() as pool: for _ in range(10): pool.starmap(worker_func, zip(my_objs)) # 将共享列表转为普通列表打印 for ob in my_objs: print(ob.id) print(list(ob.awesome_list)) if __name__ == '__main__': main()
内容的提问来源于stack exchange,提问作者P227
相关产品推荐
相关产品推荐

