Python多处理,传递包含信号量的对象引用

时间:2012-10-19 12:35:26

标签: python multiprocessing

我有这样的情景: 我创建了一个包含信号量的class元素的对象。

import multiprocessing as mpr

class Element(object):
    def __init__(self):
        self.sem = mpr.Semaphore()
        self.xyz = 33

def fun( ch ):
    a = ch.recv()
    print( a[0] )
    print( a[1].xyz )
    a[1].xyz = 99
    print( a[1].xyz )


el = Element()

( pa , ch ) = mpr.Pipe()
proc = mpr.Process(target=fun , args=( ch, ) )

proc.start()
pa.send( [ "Hallo" , el ])

print( el.xyz )

proc.join()

此代码返回此错误:

  File "/usr/lib/python2.7/multiprocessing/forking.py", line 51, in assert_spawning
    ' through inheritance' % type(self).__name__
RuntimeError: Semaphore objects should only be shared between processes through inheritance

但是,如果我从Element的声明中删除信号量,则代码可以正常工作,但分配给[1] .xyz的值将会丢失。

现在我需要通过semphore和多处理来同步一大堆对象。  那么有一些方法可以在每个对象中设置信号量并仅将引用传递给主对象吗?

import multiprocessing as mpr

class Element(object):
    def __init__(self):
        self.xyz = 33

def fun( ch ):
    a = ch.recv()
    print( a[0] )
    print( a[1].xyz )
    a[1].xyz = 99
    print( a[1].xyz )


el = Element()

( pa , ch ) = mpr.Pipe()
proc = mpr.Process(target=fun , args=( ch, ) )

proc.start()
pa.send( [ "Hallo" , el ])

print( el.xyz )

proc.join()

第二个版本不会产生任何错误,但分配给a[1].xyz = 99的值将在主进程中丢失。

1 个答案:

答案 0 :(得分:19)

我认为您不了解multiprocessing模块的工作原理。

当您通过管道发送内容时,它会在子流程中被腌制然后打开。 这意味着子进程实际上具有原始对象的副本! 这就是改变“失去”的原因。添加信号量不会改变任何东西。

如果你想在共享内存中使用一个对象,你应该使用multiprocessing.Value,即使这不处理任意类型。 可能multiprocessing.Manager正是你要找的。

另一种方法是向提供修改对象的主进程发送响应。