Python 多处理对象引用

Python multiprocessing object reference

我没有得到 python 多处理模块。 我使用函数启动一个进程,并将对象作为其参数。据我了解,它应该是该对象的精确副本。但是,如果我尝试打印该对象的地址,它在每个进程中都是相同的。怎么可能?每个过程中的地址不应该不同吗?如果它在每个进程中都是同一个对象,为什么对它的更改不是全局的,而是每个进程的局部?

我的对象定义如下:

class MyClass():

    my_field = None

    def __init__():
        self.my_field = 0

以及在单独进程中运行的函数

def function_to_run_in_process(some_object):
    print some_object

多进程的结果类似于:

<__main__.MyClass instance at 0x7f276419e5f0>
<__main__.MyClass instance at 0x7f276419e5f0>
<__main__.MyClass instance at 0x7f276419e5f0>

等等。

如果我尝试像这样更改进程内对象的某些字段:

def function_to_run_in_process(some_object, process_lock):
   process_lock.acquire()
   some_object.some_field = some_object.some_field + 1
   process_lock.acquire()
   print some_object, 'with some_field = ', some_object.some_field, 'at address: ', hex(id(some_object.some_field))

我得到的结果与此类似:

<__main__.MyClass instance at 0x7f276419e5f0>  with some_field = 1  at address  0xc5c428>
<__main__.MyClass instance at 0x7f276419e5f0>  with some_field = 1  at address  0xc5c428>
<__main__.MyClass instance at 0x7f276419e5f0>  with some_field = 1  at address  0xc5c428>

那么,如果传递的对象只是一个副本,为什么不仅对象的地址相同,而且它的字段的地址也相同?如果它们相同,为什么字段的更改不可见?

How it is possible?

每个进程都有自己的Virtual Address Space

Shouldn't address be different in every process?

没有。子进程继承其父进程的 VAS。参见 clone and fork

And if it is the same object in every process how come that changes to it are not global but local for every process?

VAS 中的进程内存页面将设置为 COPY ON WRITE。只要页面未更改,它们都会指向相同的物理内存,但是如果进行任何更改,该页面的 VAS 将映射到不同的位置。


这里有一篇关于进程内存管理的文章:http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/


如果你想在进程之间共享状态,你可以共享内存或传递消息。多处理模块可以在共享内存页中创建 python 个对象,这在 here

中有描述

但是,最好避免,尤其是如果以上所有内容对您来说都是新鲜事。