Python多处理对象引用
问题描述
我不了解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>
那么,如果传递的对象只是一个副本,为什么不仅对象有相同的地址,甚至它的字段也有相同的地址?如果它们相同,为什么对该字段的更改不可见?
解决方案
怎么可能?
每个进程都有自己的Virtual Address Space
每个进程中的地址不应该不同吗?
不。子进程正在继承其父进程的VAS。请参阅clone和fork。
VAS中的进程内存页将设置为COPY ON WRITE。只要页面没有更改,它们都将指向相同的物理内存,但是,如果进行了任何更改,该页面的VAS将映射到不同的位置。如果它在每个进程中都是同一个对象,为什么对它的更改不是全局的,而是每个进程的本地更改?
这里有一篇关于进程内存管理的文章:http://duartes.org/gustavo/blog/post/anatomy-of-a-program-in-memory/
如果您希望在进程之间共享状态,则可以共享内存或传递消息。多处理模块可以在共享内存页中创建PYTHON对象,具体说明here
不过,最好避免这样做,尤其是如果以上所有情况对您来说都是新闻。
相关文章