使用processing.Manager时对象是否重复?

时间:2014-11-24 21:12:34

标签: python process

我正在尝试使用processing.Manager在进程之间共享数据(processing.Manager.list,processing.Manager.dict,...)。但是,当我使用它时,对象是重复的:

from multiprocessing import Process, Manager


def manipulate_in_process(objects):
    objs = []
    for obj in objects:
        objs.append(obj)
    print('foo objs', objs)

def do_in_process(objects):
    print('objects', objects)
    manipulate_in_process(objects)

if __name__ == '__main__':
    manager = Manager()
    objects = [object(), object()]
    print('main objects', objects)
    shared_objects = manager.list(objects)
    process = Process(target=do_in_process, args=(shared_objects,))
    process.start()
    process.join()
    print('finish')

输出:

main objects [<object object at 0xb72a64a8>, <object object at 0xb72a64b0>]
objects [<object object at 0xb72a64a8>, <object object at 0xb72a64b0>]
foo objs [<object object at 0xb72a64e8>, <object object at 0xb72a64c0>]
finish

使用时共享对象重复: 0xb72a64a8 != 0xb72a64e8

  1. 我做错了吗?
  2. 为什么要复制这些对象?
  3. 如何使用具有processing.Manager.list / dict / etc?
  4. 的对象

1 个答案:

答案 0 :(得分:0)

在进程之间复制而不是共享对象几乎是固有的。这是单独进程的定义:它们具有单独的堆与单独的对象。

如果您想要实际的共享数据,则必须使用ValueArraysharedctypes - 当然,在这种情况下,您只能使用“原生”值和那些你可以表达的C结构。而且,即便如此,也不能保证id在整个流程中是相同的,只是价值本身就是。

Manager的要点是,您可以在服务器进程中放置一个对象,例如list,并在每个子进程中放置该对象的代理。就核心列表功能而言,列表代理看起来像一个真实的列表(迭代,索引,appendinsertindex等等。但是代理并没有试图伪造像id那样的“隐蔽”内省功能。

开箱即用的Manager可以代理的确切类型列表在Python版本之间有所不同,但您可以在您的版本的文档中找到它。自3.4起,它包含listdictNamespaceLockRLockSemaphoreBoundedSemaphore,{{ 1}},ConditionEventBarrierQueueValue。无论如何,它永远不会包含Array,因为object 除了隐藏的东西之外没有功能。

当然,您可以使用自定义代理object注册自己的类型。但我不确定您要与Manager分享的内容。

有关详细信息,请参阅Sharing state between processes;有关详细信息,请参见Managers