You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多进程Pool中全局列表变量返回为空的问题

多进程中全局变量无法同步的问题

我声明了空列表bulb_data作为全局变量并完成赋值,但用multiprocessing.Pool做多进程处理时,子进程里这个全局变量是空列表,不是已经赋值的内容。另外我还需要在每个子进程里编辑这个字典列表,并同步更新全局变量。

代码示例

from multiprocessing import Process, Pool
camera_data = [{"id": "1", "url": "cam-c.jpg", "area": "1"},
                       {"id": "2", "url": "cam-d.jpg", "area": "1"},
                       {"id": "3", "url": "cam-e.jpg", "area": "2"},
                       {"id": "4", "url": "cam-f.jpg", "area": "2"}]

bulb_data = []


def framed_images(fake):
    print(bulb_data)


if __name__ == '__main__':
    print("camera_data - ",camera_data)
    for data in camera_data:
        bulb_data.append({"url": data["url"], "bulb": False})
    print("bulb_data - ",bulb_data)
    fake_Data = bulb_data

    with Pool(processes=4) as pool:
        pool.map(framed_images, fake_Data)

当前输出

camera_data - [{'id': '1', 'url': 'cam-c.jpg', 'area': '1'}, {'id': '2', 'url': 'cam-d.jpg', 'area': '1'}, {'id': '3', 'url': 'cam-e.jpg', 'area': '2'}, {'id': '4', 'url': 'cam-f.jpg', 'area': '2'}]

bulb_data - [{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]
[]
[]
[]
[]

期望输出

[{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]
[{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]
[{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]
[{'url': 'cam-c.jpg', 'bulb': False}, {'url': 'cam-d.jpg', 'bulb': False}, {'url': 'cam-e.jpg', 'bulb': False}, {'url': 'cam-f.jpg', 'bulb': False}]

问题原因

多进程模式下,子进程会复制父进程的内存空间,但这个复制是初始化时的快照——你在if __name__ == '__main__'里给bulb_data赋值的操作,是在父进程启动后执行的,子进程启动时只会拿到全局变量初始的空列表,不会同步父进程后续的修改。另外,子进程对全局变量的修改也不会影响父进程或其他子进程,因为每个进程都有独立的内存空间。

解决方法

方法1:用initializer传递初始数据给子进程

如果只需要子进程拿到bulb_data的初始值,不需要同步修改结果,可以在创建Pool时指定初始化函数,把数据传递给每个子进程:

from multiprocessing import Pool

camera_data = [{"id": "1", "url": "cam-c.jpg", "area": "1"},
                       {"id": "2", "url": "cam-d.jpg", "area": "1"},
                       {"id": "3", "url": "cam-e.jpg", "area": "2"},
                       {"id": "4", "url": "cam-f.jpg", "area": "2"}]

bulb_data = []

def init_worker(data):
    global bulb_data
    bulb_data = data.copy()  # 将父进程的数据复制到子进程的全局变量

def framed_images(fake):
    # 在这里编辑bulb_data,比如修改对应url的bulb状态
    for item in bulb_data:
        if item["url"] == fake["url"]:
            item["bulb"] = True
    print(bulb_data)

if __name__ == '__main__':
    print("camera_data - ",camera_data)
    for data in camera_data:
        bulb_data.append({"url": data["url"], "bulb": False})
    print("bulb_data - ",bulb_data)
    fake_Data = bulb_data

    with Pool(processes=4, initializer=init_worker, initargs=(bulb_data,)) as pool:
        pool.map(framed_images, fake_Data)

方法2:用共享内存实现跨进程同步修改

如果需要子进程修改后的数据能同步回父进程或其他子进程,要使用multiprocessing.Manager提供的共享数据结构:

from multiprocessing import Pool, Manager

camera_data = [{"id": "1", "url": "cam-c.jpg", "area": "1"},
                       {"id": "2", "url": "cam-d.jpg", "area": "1"},
                       {"id": "3", "url": "cam-e.jpg", "area": "2"},
                       {"id": "4", "url": "cam-f.jpg", "area": "2"}]

def framed_images(args):
    fake, bulb_data = args
    # 修改共享列表中的元素,所有进程都会看到变化
    for item in bulb_data:
        if item["url"] == fake["url"]:
            item["bulb"] = True
    print(bulb_data)

if __name__ == '__main__':
    print("camera_data - ",camera_data)
    # 创建Manager管理的共享列表
    manager = Manager()
    bulb_data = manager.list()
    for data in camera_data:
        bulb_data.append({"url": data["url"], "bulb": False})
    print("bulb_data - ",bulb_data)
    fake_Data = bulb_data

    # 将共享列表和任务参数一起传递给子进程
    with Pool(processes=4) as pool:
        pool.map(framed_images, [(item, bulb_data) for item in fake_Data])
    
    # 父进程可以直接获取修改后的结果
    print("Final bulb_data: ", bulb_data)

注意事项

  • 普通全局变量在多进程中完全独立,子进程的修改不会影响其他进程。
  • initializer方式性能更高,适合只需要传递初始数据的场景;Manager共享结构有一定性能开销,适合需要跨进程同步数据的场景。
  • 共享列表中的字典是可变对象,修改内部属性会自动同步,但如果多个子进程同时修改同一个元素,需要加锁(multiprocessing.Lock)避免并发冲突。

内容的提问来源于stack exchange,提问作者Model Trainer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 10:45:35