Python多进程中ThreadSafeInt的self.size无法跨进程更新原因咨询
问题解析:多进程下共享内存变量未同步的原因
这个问题的核心在于多进程的内存隔离特性,以及你代码里对multiprocessing.Value的误用,咱们一步步来理清楚:
1. 多进程的内存隔离本质
Python的multiprocessing模块创建子进程时,会采用**写时复制(Copy-on-Write)**的机制:子进程会复制父进程的整个内存空间(包括对象、变量等),但只有当子进程修改某个变量时,才会真正创建该变量的独立副本。这意味着:
- 子进程里的
num对象是主进程num对象的副本,二者不是同一个内存引用; - 但
multiprocessing.Value是特殊的共享内存对象,它的底层数据存储在所有进程都能访问的共享内存块里——这也是它能实现进程间数据同步的核心。
2. 你的代码哪里错了?
看ThreadSafeInt类的setNum方法:
def setNum(self, num): with self.lock: self.size = multiprocessing.Value('i', num)
这里你犯了一个关键错误:你没有修改共享内存里的值,而是给子进程的self.size重新赋值了一个全新的Value对象。
这个新创建的Value对象只存在于子进程的内存空间里,和主进程原来的self.size指向的共享内存块没有任何关系。所以子进程修改后,主进程的self.size依然指向原来的共享内存(值还是10),自然看不到变化。
3. 正确的写法
你需要修改的是已有Value对象的value属性,而不是重新创建Value:
# ThreadSafeInt.py 修正后的 setNum 方法 def setNum(self, num): with self.lock: self.size.value = num
这样操作的是共享内存块里的实际值,所有进程访问同一个Value对象时,都会读取到最新的内容。
4. 原输出的逻辑解释
结合原代码的执行流程,输出结果就很好理解了:
- 主进程初始化
num并设置为10,打印Value = 10; - 子进程启动后,复制了主进程的
num对象,调用change函数时,给子进程副本的self.size赋值了新的Value(20)——但这个修改只在子进程内部有效; - 子进程结束后,主进程的
num对象还是原来的状态,所以打印Value = 10; - 主进程自己调用
setNum时,修改的是主进程里num对象的self.size(原代码里是创建新的Value(20)),所以打印Value = 20; - 最后打印
Done!。
额外补充:关于锁的注意点
你用的multiprocessing.RLock是支持跨进程的锁,但在原代码里它其实没起到作用——因为你是创建新的Value对象,而不是修改共享内存的值。修正代码后,锁可以保证对共享内存的修改是原子操作,避免多进程同时修改导致的竞争问题。
内容的提问来源于stack exchange,提问作者Phillip Stephens
相关产品推荐
相关产品推荐

