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

如何在子进程启动后初始化并共享multiprocessing.Manager.dict?

解决多进程启动后初始化共享字典的同步问题

问题根源

多进程启动时会复制父进程的内存空间(Windows下是重新加载整个程序),如果子进程启动后才创建multiprocessing.Manager().dict并赋值给单例,子进程持有的单例字典引用还是启动时的空对象,无法感知父进程后续更新的新共享字典引用,导致打印空内容。

解决方案1:提前创建共享字典(推荐)

在子进程启动前就初始化共享字典,确保子进程复制的是共享字典的引用,后续修改能通过IPC同步:

import multiprocessing
import time

class Singleton:
    _instance = None
    dns_list = None

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

def worker1():
    singleton = Singleton()
    while True:
        print(f"worker1 dns_list: {singleton.dns_list}")
        time.sleep(1)

if __name__ == "__main__":
    # 1. 先创建Manager和共享字典
    manager = multiprocessing.Manager()
    shared_dns = manager.dict()

    # 2. 让单例绑定共享字典
    singleton = Singleton()
    singleton.dns_list = shared_dns

    # 3. 再启动子进程
    p1 = multiprocessing.Process(target=worker1)
    p1.start()

    # 后续修改共享字典,子进程能同步获取
    time.sleep(2)
    shared_dns["example.com"] = "1.1.1.1"
    print(f"main process dns_list: {shared_dns}")

    p1.join()

解决方案2:用共享Namespace延迟初始化

如果必须在子进程启动后才初始化字典,可以用Manager.Namespace存储共享字典的引用——Namespace本身是跨进程共享的,子进程能通过它获取到后续初始化的字典:

import multiprocessing
import time

class Singleton:
    _instance = None
    ns = None  # 用共享Namespace存dns_list

    def __new__(cls):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
        return cls._instance

def worker1():
    singleton = Singleton()
    while True:
        if singleton.ns and hasattr(singleton.ns, 'dns_list'):
            print(f"worker1 dns_list: {singleton.ns.dns_list}")
        else:
            print("worker1 waiting for dns_list init...")
        time.sleep(1)

if __name__ == "__main__":
    # 先启动子进程
    p1 = multiprocessing.Process(target=worker1)
    p1.start()

    time.sleep(2)
    # 初始化共享Namespace和字典
    manager = multiprocessing.Manager()
    ns = manager.Namespace()
    ns.dns_list = manager.dict()
    ns.dns_list["example.com"] = "1.1.1.1"

    # 把共享Namespace赋值给单例
    singleton = Singleton()
    singleton.ns = ns

    print(f"main process dns_list: {ns.dns_list}")

    p1.join()

关键注意点

  • 不要在子进程启动后才给单例赋值新的共享对象引用,子进程无法感知这种引用变更;
  • Manager创建的对象(dict、Namespace)是通过IPC实现共享的,必须确保子进程持有正确的共享对象引用;
  • 单例模式在多进程中每个进程都会有自己的实例,只有绑定的共享对象才是跨进程同步的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:01:56