You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动