2011-07-14 12 views
3

Python subprocessライブラリを使用してサブプロセスを生成した後、を使用して子プロセスからのメッセージをシリアル化されたデータを含む親プロセスに渡します。私は親が(stdinを介して)このデータに適用された関数の結果を返すことを望みます。本質的にはstdout/stderrファイル記述子でos.fsyncを呼び出すと、サブプロセスが終了する

、私はこのような何かを行うサブプロセス内の機能を持っている:

sys.stderr.write("some stuff to write") 
# some time later 
some_var = sys.stdin.read() 

はしかし、これはstderr入力を待っている間に、親をロック完了したので、私は呼び出そうとしました:

sys.stderr.flush() 
os.fsync(sys.stderr.fileno()) 

ただし、これは機能しません。 os.fsyncが実行された後は何も実行されません。また、親プロセスでproc.poll()と呼ぶと、子の戻りコードは1になります。

これを防ぐにはどうすればよいですか?私は別のアプローチを検討すべきでしょうか?

答えて

2

私は別の方法を考えます。 一意のプロセス(multiprocessing.Process)を使用して、2つのキューを使用して(multiprocessing.Queue)その1つを入力用に、もう1つを出力用に使用することができます。プロセスを開始するに 例:

import multiprocessing 

def processWorker(input, result): 
    work = input.get() 
    print work 
    result.put(work*work) 

input = multiprocessing.Queue() 
result = multiprocessing.Queue() 

p = multiprocessing.Process(target = processWorker, args = (input, result)) 
p.start() 

input.put(2) 
res = result.get(block = True) 
print res 

その後、あなたは再びそれを渡して繰り返すことがあります。マルチ処理の使用.Queueは、stdout/err解析に頼る必要がなく、関連する制限も回避するので、より堅牢です。 さらに、より多くのサブプロセスを簡単に管理できます。

はその後、あなたは例えば、最大で待機するために呼び出す取得したいどのくらいにタイムアウトをも設定することができます。

import queue 
try: 
    res = result.get(block = True, timeout = 10) 
except Queue.Empty: 
    print error 
1

ここでは、根本的なアプローチを変更することなく、I/Oのデッドロックを防ぐことができるかです。子で:

import os, fcntl 
map(lambda f: fcntl.fcntl(f.fileno(), fcntl.F_SETFL, os.O_NONBLOCK), 
    (sys.stdin, sys.stdout, sys.stderr)) 

親では、子との間のパイプファイル記述子についても同じことをします。その後、select.select()を使用して通信すると、これらのロックアップはなくなります。ただし、書き込みを行う前でもselect()を使用する必要があります。読み書きしようとするとEAGAINエラーが発生し、アプリケーションロジックによっては不定期な待機状況が発生する可能性があります。

子プロセス機能が組み込まれているTwistedフレームワークを調べることを正直にお勧めします:http://twistedmatrix.com/documents/current/core/howto/process.html

関連する問題