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

Python多进程修改字典后主线程无法同步变更问题求助

子进程修改字典后主线程无法获取变更的问题分析

环境与需求

  • Python版本:3.9(3.12版本下结果一致)
  • 需求目标:让子进程修改字典后,主线程能获取到这些变更

问题代码

import multiprocessing as mp
import sys

def my_func(result: dict):
    print(f'variable address at worker: {hex(id(result))}', file=sys.stderr)
    result["test"] = "test"
    print(f'{result}', file=sys.stderr)

result = {}
print(f'variable address at main thread: {hex(id(result))}', file=sys.stderr)
my_worker = lambda : my_func(result)

# 子进程执行
p = mp.Process(target=my_worker)
p.start()
p.join()

print(f'result at main thread after execution: {result}', file=sys.stderr)

# 同一进程内手动执行
my_worker()
print(f'result at main thread after manual execution: {result}', file=sys.stderr)

print(sys.version)

执行输出

variable address at main thread: 0x6ffffff39580
variable address at worker: 0x6ffffff39580
{'test': 'test'}
result at main thread after execution: {}
variable address at worker: 0x6ffffff39580
{'test': 'test'}
result at main thread after manual execution: {'test': 'test'}
3.9.16 (main, Mar  8 2023, 22:47:22)
[GCC 11.3.0]

问题原因

多进程的核心特性是每个进程拥有独立的内存空间。虽然打印的内存地址看起来相同,但这只是进程自身虚拟地址空间内的标识,不同进程的虚拟地址对应不同的物理内存。

子进程启动时,会通过**写时复制(Copy-on-Write)**机制复制父进程的内存数据。当子进程修改字典时,会在自己的内存空间里创建该字典的副本,修改的只是这个副本,和主进程的字典完全是两个独立对象,所以主线程看不到任何变更。

而直接调用my_worker()属于同一进程内的函数调用,修改的是同一个字典对象,所以主线程能看到结果。

解决方案

要实现跨进程的数据共享,需要使用multiprocessing模块提供的共享数据结构或进程间通信(IPC)机制,比如Manager().dict()、Queue或Pipe。这里以Manager为例:

修改后的代码

import multiprocessing as mp
import sys

def my_func(result):
    print(f'variable address at worker: {hex(id(result))}', file=sys.stderr)
    result["test"] = "test"
    print(f'{result}', file=sys.stderr)

if __name__ == "__main__":
    # 使用Manager创建可跨进程共享的字典
    with mp.Manager() as manager:
        result = manager.dict()
        print(f'variable address at main thread: {hex(id(result))}', file=sys.stderr)
        
        # 启动子进程执行
        p = mp.Process(target=my_func, args=(result,))
        p.start()
        p.join()
        
        print(f'result at main thread after execution: {result}', file=sys.stderr)
        
        # 同一进程内手动执行
        my_func(result)
        print(f'result at main thread after manual execution: {result}', file=sys.stderr)
        
        print(sys.version)

方案说明

mp.Manager()会创建一个独立的服务进程,所有对manager.dict()的操作都会通过IPC转发到这个服务进程处理。这样,子进程和主进程操作的是同一个由服务进程维护的共享字典,修改会实时同步,主线程就能获取到子进程的变更。

内容的提问来源于stack exchange,提问作者Francisco Javier Rojas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 16:45:19