2012-11-30 10 views
5

私のプロジェクトではマルチプロセッシングを使用しています。私は結果を待ち行列に入れるワーカー関数を持っています。すべてうまく動作します。しかし、xの大きさが増えるにつれて(私の場合xは配列です)何かが間違っています。pythonでのマルチプロセッシングがブロックされています

def do_work(queue, x): 
    result = heavy_computation_function(x) 
    queue.put(result) # PROBLEM HERE 

def parallel_something(): 
    queue = Queue() 
    procs = [Process(target=do_work, args=i) for i in xrange(20)] 
    for p in procs: p.start() 
    for p in procs: p.join() 

    results = [] 
    while not queue.empty(): 
     results.append(queue.get) 

    return results 

私はPythonのプロセスが動作したが、その後何かが起こると、すべてのプロセスが実行されているが、何もしないされている監視システムで参照してください。ここに私のコードの簡易版です。これは、ctrl-Dとタイプするときに得られるものです。

pid, sts = os.waitpid(self.pid, flag) 
KeyboardInterrupt 

私はいくつかのテストを行います。問題は、実際にはキューに結果を入れることに似ているように見えますが、結果をすべて入れても、目的がない場合は、

+4

キューオブジェクトを新しいプロセスに渡すことは決してありません。 'Process'の' args'も 'タプル'でなければなりません。 'args =(queue、i)'に変更してみてください。あなたの 'queue.get'は' queue.get() 'になるようにいくつかの括弧を必要とします。 – Wessie

答えて

3

まあ、それはpythonのQueueモジュールのいくつかのバグのようです。実際に作品を..everything ..

from multiprocessing import Manager 

queue = Manager().Queue() 

を使用していますが、おそらくデッドロックが発生している理由.. :)

+0

違いは単純に 'Queue()'の代わりに 'Manager()。Queue()'をインスタンス化していることです。これは 'Manager .__ init __()'が最初の形式で呼び出され、2番目の形式では呼び出されないことを意味します。 – Patrick

5

私はまだ知りません。 programming guidelinesから

:これは、キューを使用するたびに、プロセスが参加される前に、キューに置かれているすべての項目が最終的に削除されることを確認する必要があることを意味

。さもなければ、キューにアイテムを置いたプロセスが終了することを確かめることはできません。非デーモンプロセスは自動的に結合されることにも注意してください。

可能な修正もこのページで提案されています。プロセスが結合されていない場合でも、プロセスがリソースを「占有」しているわけではありません。つまり、プロセスが操作を完了した後(おそらくlocksを使用して)、キューに入れられたデータを取り出し、後でプロセスに参加させることができます。

関連する問題