Python多进程向同一列表追加元素失败问题排查
问题原因分析与修复方案
嘿,我来帮你捋清楚为啥执行后列表是空的,你的代码里有两个核心问题:
1. 未定义变量导致函数执行失败
你的foo函数里有一行单独的a,这个变量根本没定义,会直接触发NameError异常。子进程执行到这一行就报错终止了,根本没机会执行到L.append(n)这一步,所以共享列表自然不会有任何元素被添加。
你可以把这行无用的a删掉,或者如果是测试代码不小心留下的,直接移除即可。
2. 未等待异步任务执行完成
你用pool.apply_async()提交了异步任务,但主进程没有等待这些任务完成就直接执行print(L)了。进程池的任务是在后台子进程里运行的,主进程的执行速度比子进程快得多,此时子进程可能还没开始处理任务,所以打印出来的列表就是空的。
解决办法是在打印列表前,先关闭进程池并等待所有任务结束:
- 调用
pool.close():禁止向进程池提交新任务 - 调用
pool.join():等待进程池里所有子进程完成任务
修正后的完整代码
import multiprocessing as mp def foo(n, L): # 移除未定义的变量a L.append(n) if __name__ == "__main__": # Windows系统下必须加这个判断,避免进程启动时重复导入代码 pool = mp.Pool(processes=2) manager = mp.Manager() L = manager.list() l = [[1,2],[3,4],[5,6],[7,8]] # 提交所有异步任务 tasks = [pool.apply_async(foo, args=[n, L]) for n in l] # 等待所有任务完成 pool.close() pool.join() print(L)
执行这段代码后,就能得到预期的输出(元素顺序可能因进程调度略有不同):[[1, 2], [3, 4], [5, 6], [7, 8]]
内容的提问来源于stack exchange,提问作者HappyPy




