2010-12-02 6 views
1

私はUbuntu 8.10でPython 2.6.5を実行しています。Pythonプロセス内で付加価値を返すことができません

私が進めているプロジェクトでは、いくつかのプロセスを同時に実行し、それぞれの出力をそれぞれのリストに保存する必要があります。私はプロセスから直接出力値を返すことができないので、出力リストを引数としてターゲット関数に渡し、出力をそのリストに追加しています。問題は、プロセスを実行した後でそのリストにアクセスしようとすると、そのリストはまだ空であるということです。私が持っている問題の簡略化されたバージョンは、エラーメッセージと共に以下にあります。

コード:

from multiprocessing import Process 
import sys, math, os,commands 

outputs = [] 

def calculate(a,b,outputs): 
    c = a*b 
    outputs.append(c) 
    #return c 

outputs1 = [] 

p1 = Process(target = calculate, args = (2,3,outputs1)) 

p1.start() 
p1.join() 

print 'len(outputs1) = ' + str(len(outputs1)) 

print 'outputs1 = ' + str(outputs1[0]) 

エラー:

len(outputs1) = 0 
Traceback (most recent call last): 
    File "append_test.py", line 23, in <module> 
    print 'outputs1 = ' + str(outputs1[0]) 
IndexError: list index out of range 

私はデータを破壊の恐れのために他人の完全に独立した各プロセスを維持しようとしています。私は、マルチプロセッシングからArrayモジュールを使用しようとしましたが、appendはリストに固有のようです。 Processの代わりにThreadを使って全く同じコードを実行すると、問題のない出力が得られ、これがメモリ共有の問題だと私は思っています。

+0

コードの書式を修正してください。特に、Pythonコードでは、どのようにインデントされているかを確認することが重要です。 –

+0

AMPQのようなものを使用すると、サーバマシン間で作業を簡単に配布できます。 –

+2

'multiprocessing.Queue'sの使用を検討しましたか? – nmichaels

答えて

3

別々のプロセスを使用すると、各プロセスはメモリ内のすべてのものの独自のコピーを取得します。そのため、親プロセスはoutputsに何も見えません。それぞれの子プロセスは、outputsという独自のコピーに追加しています。

何らかのプロセス間通信を使用する必要があります。 Pythonのmultiprocessingライブラリは、このために2つの機能、すなわちpipes and queuesを提供します。使用例

Queue

>>> from multiprocessing import Process, Queue 
>>> def f(q): q.put("hello from the child process") 
... 
>>> q = Queue() 
>>> p = Process(target=f, args=(q,)) 
>>> p.start() 
>>> p.join() 
>>> q.get() 
'hello from the child process' 
+0

'multiprocessing'モジュールの[プログラミングガイドライン - すべてのプラットフォーム](http://docs.python.org/library/multiprocessing.html#all-platforms)の「キューを使用するプロセスへの参加」のサブセクションでは、 「キューを使用するたびに、キューに入れられたすべてのアイテムが最終的に削除されてプロセスが結合されることを確認する必要がある」ことを推奨しています。私はこれが、この回答のコードの 'q.get()'が 'pの前に*移動されるべきであることを意味すると信じています。join() 'を使って、ドキュメントの例に示すようにします。 – martineau

+0

良い点。 (ドキュメントでは、パイプとキューのセクションでこれについて言及するかもしれません。) –

0

multiprocessingモジュールのオンラインドキュメントの中Exchanging objects between processesというタイトルのセクションでは、[のみ]「プロセス間通信チャネルの2種類をサポートしています」と行くと言っていますキューおよびパイプ。特にそれはではなく、のようなオブジェクトを指します。はありません。これは、2つのプロセスがメモリAFAIKを共有しないため意味をなさない。

わかりませんが、サブプロセスがサブプロセスを作成しないようにするには、if __name__ == '__main__':節の中にプロセスを作成して起動するコードのセクションを配置する必要があると思われます。

要約すると、プロセス間通信にこれらの2つのうちの1つを使用するためには、作業をやり直す必要があると思います。キューは私にとっては論理的な選択肢のようです。

関連する問題