サブプロセスモジュールを使用してプロセスと適切に対話する方法
-
22-07-2019 - |
質問
サブプロセスモジュールを使用して別のプログラムの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
解決
例に100%適合しませんが、根本的な問題を理解するのに役立ちます。プロセスPは子Cを開始します。子Cはstdoutに何かを書き込みます。 Cのstdoutは、4096文字のバッファーを持つパイプであり、出力はそれよりも短くなります。現在、Cは入力を待機しています。 Cの場合、すべて問題ありません。
Pは、OSがCの出力バッファーをフラッシュする理由を認識しないため(出力データがほとんどないため)、出力を待機します。 PはCの出力を取得しないため、Cには何も書き込まないため、CはPからの入力を待機してハングします。
修正:パイプへの書き込みのたびにフラッシュを使用して、OSにデータを強制的に送信させます今。
あなたの場合、メインのwhileループに proc.stdin.flush()
を追加し、印刷後に子ループに sys.stdout.flush()
を追加します問題を修正する必要があります。
また、他のプロセスから読み取るコードをスレッドに移動することも検討する必要があります。ここでのアイデアは、データがいつ到着するかを決して知ることはできないということであり、スレッドを使用すると、結果を処理するコードを記述するときにこれらの問題を理解するのに役立ちます。
ここでは、新しいPython 2.6のドキュメントを表示したかったのですが、フラッシュの問題については説明していません。(まあ...