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

Windows下新Process无法获取更新后类属性值的问题排查

Windows下多进程无法获取更新后类属性的原因解析

问题现象

先看代码及对应输出:

class A:
    a1 = {}

def fp(a):
    print(a.a1)

if __name__ == '__main__':
    a = A()
    A.a1.update({"p":"1"}) # 更新类变量
    p1 = Process(target=fp, args=(a,))
    p1.start()

    A.a1 = {"p":"2"}
    # print('--', a.a1) # {'p': '2'}
    p2 = Process(target=fp, args=(a,))
    p2.start()

    a.a1 = {"p":"3"} # 不会修改A.a1
    # print('--', A.a1) # {'p': '2'}
    p3 = Process(target=fp, args=(a,))
    p3.start()

输出结果:

{}
{}
{'p': '3'}

核心原因:Windows的进程创建机制

Windows系统中,Python的multiprocessing.Process创建子进程时,不会像Linux那样通过fork复制父进程内存空间,而是启动全新的Python解释器,重新导入当前模块。

这意味着:子进程启动时,模块内的类定义会被重新执行,类属性会被重置为定义时的默认值(即A.a1 = {})。父进程对类属性的所有修改,都无法被子进程感知——因为二者的类属性属于不同内存空间的独立对象。

逐案例解析

案例1:A.a1.update({"p":"1"})

父进程通过update修改了类属性A.a1的内容,但子进程启动时重新初始化类属性为{},因此打印空字典。

案例2:A.a1 = {"p":"2"}

父进程给类属性A.a1重新赋值了新字典,但子进程依然会将类属性重置为初始的{},所以打印结果还是空字典。

案例3:a.a1 = {"p":"3"}

这一操作并非修改类属性,而是给实例a新增了实例属性a1(类属性仍为{"p":"2"})。当实例a被传递给子进程时,Python会通过pickle序列化实例,实例属性会被一并传递。子进程反序列化得到实例后,访问a.a1会优先读取实例属性,因此打印{'p': '3'}。

相关错误说法纠正

部分资料提到“用instance.attr=设置类成员”是错误的——instance.attr=只会给当前实例添加或覆盖实例属性,完全不会修改类本身的属性。只有Class.attr=的方式能修改类属性,但这种修改在Windows多进程场景下无法被子进程继承。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 02:52:25