3

Pythonsubprocessライブラリを使用してサブプロセスを生成した後stderr、子プロセスからシリアル化されたデータを含む親プロセスにメッセージを渡すために使用しています。stdin次に、このデータに適用された関数の結果を(経由で)親に返すようにします。

本質的に、私はサブプロセス内に次のような関数を持っています。

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であるように見えます。

これを防ぐために何ができますか?別のアプローチを検討する必要がありますか?

4

2 に答える 2

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

次に、それをもう一度渡すことを繰り返すことができます。multiprocessing.Queueの使用は、stdout / err解析に依存する必要がなく、関連する制限も回避できるため、より堅牢です。さらに、より多くのサブプロセスを簡単に管理できます。

次に、get呼び出しを最大で待機する時間にタイムアウトを設定することもできます。例:

import queue
try:
    res = result.get(block = True, timeout = 10)
except Queue.Empty:
    print error
于 2011-07-14T21:41:55.670 に答える
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

于 2011-07-14T21:51:58.203 に答える