多进程填充大字典时遭遇NameError错误求助
多进程填充大字典时遭遇NameError错误求助
嘿,我来帮你排查这个问题~你遇到的NameError: name 'iddic' is not defined其实是多进程模型的特性导致的,而且还有个隐藏的坑等着你,我慢慢给你说清楚:
问题根源
Python的multiprocessing模块创建的子进程,每个都有独立的内存空间——主进程里定义的全局变量iddic,并不会自动“复制”到子进程的环境中。当子进程执行populate_dictionary函数时,它的内存里根本找不到iddic这个变量,自然就抛出NameError了。
另外还有个隐藏问题:就算你解决了iddic的问题,最后主进程打印的finaldic还是空的!因为子进程里修改的finaldic是它自己内存里的副本,和主进程的finaldic完全不是同一个东西,子进程的修改不会同步到主进程。
解决方案
我给你两种常用的解决思路,你可以根据自己的场景选择:
方案1:通过参数传递字典+队列收集结果(适合字典只读的场景)
把iddic作为参数传给子进程,同时用队列收集每个子进程处理的结果,最后在主进程合并:
import multiprocessing def create_initial_dictionary(): # 不用全局变量,直接返回字典更清晰 return {'celia': 14, 'pierre': 12, 'picasso': 11, 'pikachu': 19} def populate_dictionary(names, iddic, result_queue): # 子进程处理自己的任务,生成子结果字典 sub_result = {} for nam in names: sub_result[nam] = 2 * iddic[nam] # 把结果放到队列里传给主进程 result_queue.put(sub_result) if __name__ == "__main__": iddic = create_initial_dictionary() finaldic = {} # 创建队列用于进程间传递数据 result_queue = multiprocessing.Queue() # 拆分任务 list_1 = list(iddic.keys())[:2] list_2 = list(iddic.keys())[2:] # 创建子进程,把需要的参数都传进去 p1 = multiprocessing.Process(target=populate_dictionary, args=(list_1, iddic, result_queue)) p2 = multiprocessing.Process(target=populate_dictionary, args=(list_2, iddic, result_queue)) p1.start() p2.start() # 从队列取出子结果,合并到最终字典 finaldic.update(result_queue.get()) finaldic.update(result_queue.get()) p1.join() p2.join() print(finaldic) # 输出: {'celia': 28, 'pierre': 24, 'picasso': 22, 'pikachu': 38}
方案2:用Manager创建共享字典(适合需要直接共享修改的场景)
如果希望子进程直接修改同一个字典,可以用multiprocessing.Manager创建支持进程间共享的字典:
import multiprocessing def create_initial_dictionary(): return {'celia': 14, 'pierre': 12, 'picasso': 11, 'pikachu': 19} def populate_dictionary(names, iddic, finaldic): # 直接修改共享字典,主进程能同步看到变化 for nam in names: finaldic[nam] = 2 * iddic[nam] if __name__ == "__main__": iddic = create_initial_dictionary() # 使用Manager创建进程间共享的字典 with multiprocessing.Manager() as manager: finaldic = manager.dict() list_1 = list(iddic.keys())[:2] list_2 = list(iddic.keys())[2:] p1 = multiprocessing.Process(target=populate_dictionary, args=(list_1, iddic, finaldic)) p2 = multiprocessing.Process(target=populate_dictionary, args=(list_2, iddic, finaldic)) p1.start() p2.start() p1.join() p2.join() # 可选:把共享字典转成普通Python字典 finaldic = dict(finaldic) print(finaldic) # 输出: {'celia': 28, 'pierre': 24, 'picasso': 22, 'pikachu': 38}
总结一下
- 多进程之间不共享全局变量,必须通过参数传递或者进程间通信机制(队列、共享对象等)来传递数据。
- 如果你只是需要读取某个数据(比如
iddic),直接传参数更高效;如果需要多个进程修改同一个对象,就用Manager或者其他共享内存工具。
备注:内容来源于stack exchange,提问作者gustavjaune
相关产品推荐
相关产品推荐

