7

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

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分配给 a[1].xyz 的值将丢失。

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

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将在主进程中丢失。

4

1 回答 1

25

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

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

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

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

于 2012-10-19T16:55:39.453 回答