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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:59:37