2012-10-19 11 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というは失われます。

これで、セムフォーとマルチプロセッシングでオブジェクトの大きなコレクションを同期する必要があります。 したがって、すべてのオブジェクトにセマフォを設定し、メインオブジェクトへの参照のみを渡す方法はありますか?

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

セマフォがプロセスの属性である必要があり、そのセマフォをプロセスに送信できないことを示すエラーはクリアされています。ですから、基本的にプロセスから継承し、実行するなどを定義する必要があります...しかし、それはあなたがやろうとしていることがより曖昧になります。 –

+0

多分、セマフォの配列を最初に割り当てて、sem_indexをElementオブジェクトの中に置いておくだけかもしれませんか? – cdleonard

+0

配列を渡すと同じ問題が別の方法で再現されますが、問題はセマフォであり、コンテナではありません。 – Giggi

答えて

13

multiprocessingモジュールの仕組みを理解していないと思います。

パイプ経由で何かを送信すると、サブプロセスでピクルされ、次にアンピクルされます。 これは、サブプロセスが実際に元のオブジェクトのコピーを持っていることを意味します! 変更が「失われた」のはこのためです。セマフォを追加すると何も変わらないでしょう。

オブジェクトを共有メモリに格納する場合は、任意の型を処理しなくても、multiprocessing.Valueを使用する必要があります。 おそらくmultiprocessing.Managerがあなたが探しているものです。

他の方法は、修正されたオブジェクトを提供するメインプロセスに応答を送信することです。

関連する問題