【问题标题】:Python multiprocessing object referencePython 多处理对象参考
【发布时间】:2015-09-27 12:54:49
【问题描述】:

我没有得到 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>

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

【问题讨论】:

  • 如果对象只是一个副本,为什么要获取锁?这样就没有同时访问的风险了。

标签: python python-multiprocessing object-reference


【解决方案1】:

这怎么可能?

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

每个流程的地址不应该都不一样吗?

没有。子进程继承其父进程的 VAS。请参阅clonefork

如果它在每个进程中都是同一个对象,为什么对它的更改不是全局的,而是每个进程的本地的?

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


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


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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-07
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 2014-09-05
    • 2013-03-29
    • 1970-01-01
    相关资源
    最近更新 更多