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

Python多进程fork模式下资源共享疑问:子进程变量ID为何相同?

为什么Linux下Python多进程中子进程的self.x ID相同,但进程间没有资源共享?

先贴出你的测试代码和运行结果:

import multiprocessing as mp
class Job:
    def __init__(self,name):
        self.name=name
class A:
    def __init__(self,x):
        self.x=x
    def run(self,job):
        self.x+=1
        print(id(self.x),self.x,job.name)
    def mul_process_test(self):
        j1=Job('hello')
        j2=Job('world')
        p1=mp.Process(target=self.run,args=(j1,))
        p2=mp.Process(target=self.run,args=(j2,))
        p1.start()
        p2.start()
        p1.join()
        p2.join()
if __name__ =='__main__':
    a=A(1)
    a.mul_process_test()
    print(id(a.x),a.x)

运行结果:

10919360 2 hello
10919360 2 world
10919328 1

这个现象其实是两个知识点共同作用的结果,咱们慢慢拆解:

1. Linux下fork的写时复制机制与进程独立性

你提到的默认fork模式,在创建子进程时,系统会复制父进程的整个地址空间(但采用写时复制Copy-On-Write策略)——简单说就是,一开始子进程和父进程共享物理内存,但只要任何一方对内存进行写入操作,系统就会为写入的部分创建独立的副本。

你的两个子进程启动时,都会复制父进程里的A实例a,但执行self.x +=1时,因为整数是Python的不可变类型,这一步其实是创建了一个新的整数对象2,再赋值给self.x——这个新对象是在子进程自己的地址空间里生成的,和父进程、另一个子进程的对象完全没关系。

2. Python的小整数缓存池导致id重复

Python为了优化性能,会对**-5到256之间的整数进行缓存**——在同一个进程里,这些整数只会被创建一次,每次引用都是指向同一个对象,所以它们的id()是相同的。

而fork出来的子进程会完全复制父进程的内存布局,包括小整数缓存池在虚拟内存中的位置。所以每个子进程里的整数2,都会被放在虚拟内存的同一个位置(也就是id()返回的那个值)。但要注意:这个id是进程内的虚拟地址,不是物理内存地址!两个子进程的2虽然id看起来一样,但它们是各自进程里的独立对象,物理内存上完全不共享。

至于主进程里的1id和子进程里的2不同,只是因为1和2在小整数池里的虚拟地址本来就不一样而已。

总结

三个进程之间完全没有资源共享,子进程里self.x的id相同只是巧合:因为小整数缓存池在每个fork出来的子进程里的虚拟内存布局一致,导致同一个小整数的虚拟地址(也就是id()返回值)相同,但它们是各自进程的独立对象,修改子进程的self.x不会影响其他进程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:51:46