Python多进程中传递对象会生成新实例吗?为何对象ID不一致?
多进程传参时对象ID不同的原因解析
你的观察完全正确——子进程里的q确实是原对象的副本,ID不同的核心原因是多进程的内存隔离机制,以及multiprocessing传参的底层逻辑:
1. 多进程的内存隔离特性
每个进程都拥有独立的虚拟内存地址空间,进程之间的内存是完全隔离的。你打印的id(q)其实是对象在当前进程内存中的地址,这个地址只在当前进程内有意义,跨进程对比没有参考价值——哪怕两个进程里的对象ID相同,它们也是完全独立的两个对象,更别说这里的ID不同了。
2. multiprocessing传参的底层逻辑
当你把对象传入multiprocessing.Process的args参数时,multiprocessing会用pickle模块对对象进行序列化(把对象转换成字节流),然后通过进程间通信机制(比如管道)把字节流传给子进程;子进程再对字节流进行反序列化,重新构建出一个新的对象。
所以你在子进程里拿到的q,是原Queue对象序列化后重建的副本,它的内存地址(也就是id)自然和主进程里的原对象不同。
不过别担心,对于multiprocessing.Queue这种专门设计的跨进程通信对象来说,虽然对象是副本,但它们底层共享了同一个通信管道,所以功能是连通的——比如你在子进程里往q里放数据,主进程完全可以从原q里取到,这才是Queue的核心作用。
验证示例
你可以修改代码验证这个特性:
z1.py
import multiprocessing from z2 import fun2 def fun(): q = multiprocessing.Queue() print('in fun', id(q)) p = multiprocessing.Process(target=fun2, args=(q,)) p.start() p.join() print('主进程取到数据:', q.get()) if __name__ == '__main__': fun()
z2.py
def fun2(q): print('in fun2', id(q)) q.put('来自子进程的数据')
运行后你会发现,虽然两个q的ID不同,但主进程确实能拿到子进程放入的数据,说明它们的通信是正常的。
内容的提问来源于stack exchange,提问作者yoismebro
相关产品推荐
相关产品推荐

