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

Gig*_*ggi 6 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()
Run Code Online (Sandbox Code Playgroud)

此代码返回此错误:

  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
Run Code Online (Sandbox Code Playgroud)

但是,如果我从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()
Run Code Online (Sandbox Code Playgroud)

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

Bak*_*riu 19

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

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

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

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