2012-10-19 62 views
6

我有這樣一個場景: 我創建了一個包含信號量的類元素的對象。Python多處理,傳遞一個對象引用包含一個信號量

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和multiprocessing同步一個大對象集合。 所以有一些方法可以在每個對象中設置一個信號量並只傳遞給主對象的引用?

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() 

第二個版本dot't產生任何錯誤,但分配給a[1].xyz = 99值將在主過程中丟失。

+0

你的錯誤很明顯,它表明信號量應該是進程的一個屬性,你不能發送給他。所以基本上你需要從Process繼承並定義一個'run'等等......但是你想要做的更加模糊。 –

+0

也許你可以在開始時分配大量的信號量,並且只傳遞一個sem_index到Element對象中? – cdleonard

+0

傳遞數組以不同方式重現相同的問題,問題出在信號量上,而不是容器中。 – Giggi

回答

13

我不認爲你瞭解multiprocessing模塊是如何工作的。

當您通過管道發送某些內容時,它會被醃漬,然後在子流程中取消粘貼。 這意味着子進程實際上有一個拷貝的原始對象! 這就是爲什麼變化是「失去」。添加信號燈不會改變任何東西。

如果你想要共享內存中的對象,你應該使用multiprocessing.Value,儘管這不能處理任意類型。 可能multiprocessing.Manager是你在找什麼。

另一種方式是將響應發送給提供修改對象的主進程。

相關問題