2011-06-29 9 views
0

Popenを使ってテストC++プログラムを呼び出すPythonプログラムがあります。テスト用のC++プログラムは単に0-99999をstdoutに書き出します。 Pythonプログラムには、別々のプロセスとして実行する必要がある2つの関数があります。 1つの関数funcAは、C++プログラムを起動し、stdoutパイプから整数を読み取り、それらの整数を共有キューに挿入する必要があります。もう1つの関数funcBは、Queueが空になるまで、Queueの整数を読み取り、出力する必要があります。私はいくつかの問題/私は下に私のコードと一緒にその下に掲載される質問があります。Python:サブプロセス、パイプデータ、マルチプロセスに関する質問

  1. funcAが(C++プログラム)が終了するまで、funcAがC++プログラムのstdoutから読み込む正しい方法は何ですか?
  2. すべてのintが処理されるまでfuncBが共有キューから読み込む正しい方法は何ですか?

質問1の私の現在の方法はうまくいきますが、キューがいっぱいになるなどチェックしない問題があるかもしれません。また、すべての数字がプリントアウトされず(約98000で停止します)、これはfuncAと何らかの関係があり、共有キューを終了して中断させる可能性がありますか?私は質問2のために何をすべきか正確には分かっていません。なぜなら、ドキュメンテーションは並行処理環境で空に依存することができず、しばらく(1)使用したくないということを述べているからです。

import multiprocessing 
import subprocess 
import Queue 

def funcA(intQueue): 
    # call C++ program 
    handle = subprocess.Popen(['../C++/C++.exe'], stdout=subprocess.PIPE) 

    while(handle.returncode == None): 
     handle.stdout.readline() 
     intQueue.put(handle.stdout.readline()) 
     handle.poll() 

def funcB(intQueue): 
    try: 
     while(1): 
      print intQueue.get(True, 2) 
    except Queue.Empty: 
     pass 

if __name__ == "__main__": 
    # shared Queue for all the processes 
    intQueue = multiprocessing.Queue() 

    # producer - receives ints from the C++ stdout and inserts into Queue 
    multiprocessing.Process(target=funcA, args=(intQueue,)).start() 

    # consumer - prints ints from the Queue 
    multiprocessing.Process(target=funcB, args=(intQueue,)).start() 

答えて

1

誰もこれと同じ問題に出くわす場合:私は、リストがhandle.stdout.readの分割(から返されたときに壊しながら、(1)を使用し、質問1について

)は、(1の長さを持っていますこれはパイプから何も返されなかったことを意味します)。質問2については

私はこの記事で説明したポイズンピル方法使用:http://www.doughellmann.com/PyMOTW/multiprocessing/communication.html

+0

私の質問1解決策は、C++プログラムがPythonプログラムが処理しているよりも遅い出力を生成している場合に問題になります。 –

2

このように、Popencommunicate方法を使用する:キューとして

handle = subprocess.Popen(['../C++/C++.exe'], stdout=subprocess.PIPE) 
out, err = handle.communicate() # this will block until the underlying subprocess exits 

、データ構造がクエリにメソッドを定義し、それが満杯または空の場合、キューを述べました。これらを利用する。

+0

を伝える使用しての問題は、あなたが言ったように、それは根本的なサブプロセスが終了するまでブロックします、ということです。私は間違いなくこれを望んでいない。私が実行している実際のC++プログラムは、すべての出力を提供するために長い時間がかかるかもしれません。また、ドキュメントには、並行処理を実行するときにfull()およびempty()を信頼できないことが記載されています。ですから、私はprocBを実行し続けるべきかどうかを判断するためのチェックとしてそれらを使用したくないでしょう。 –

+0

最初に対処するには、各 '.communicate()'呼び出しを独自のスレッドで生成するか、スレッドプールを使用するだけです。 – Santa

+0

2番目の問題に対処するために、それらは信頼されていません。ロック、イベントオブジェクトなど、あるいは適切なコンカレントプログラミング構造を使用することで、スレッドセーフなものにすることができます。 – Santa