12

subprocess モジュールを使用して別のプログラムの stdio をリダイレクトする際に問題があります。stdout から読み取るだけでハングし、Popen.communicate() は機能しますが、読み取り/書き込み後にパイプを閉じます。これを実装する最も簡単な方法は何ですか?

私はWindowsでこれをいじっていました:

import subprocess
proc = subprocess.Popen('python -c "while True: print \'Hi %s!\' % raw_input()"',
                        shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
                        stderr=subprocess.STDOUT)
while True:
    proc.stdin.write('world\n')
    proc_read = proc.stdout.readline()
    if proc_read:
        print proc_read
4

1 に答える 1

20

あなたの例に 100% 適合しませんが、根本的な問題を理解するのに役立ちます: プロセス P が子 C を開始します。子 C はその stdout に何かを書き込みます。C の stdout は、4096 文字のバッファーを持つパイプであり、出力はそれよりも短くなります。ここで、C は何らかの入力を待ちます。Cの場合、すべて問題ありません。

P は、OS が C の出力バッファーをフラッシュする理由を認識しないため (データがほとんどないため)、決して出力されない出力を待ちます。P は C の出力を取得しないため、C には何も書き込まれず、C は P からの入力を待機してハングします。

修正: パイプへのすべての書き込み後にフラッシュを使用して、OS に今すぐデータを送信させます。

あなたの場合、proc.stdin.flush()メインの while ループに追加しsys.stdout.flush()、印刷後に子ループに a を追加すると、問題が解決するはずです。

また、他のプロセスから読み取るコードをスレッドに移動することも検討する必要があります。ここでの考え方は、データがいつ到着するかを知ることはできず、スレッドを使用すると、結果を処理するコードを作成する際にこれらの問題を理解するのに役立つということです。

この場所では、新しい Python 2.6 のドキュメントをお見せしたかったのですが、フラッシュの問題についても説明していません :( まあ ...

于 2009-01-14T14:16:38.607 に答える