2017-07-03 7 views
1

サブプロセスの出力を実際に待たずに簡単に集める方法はありますか?サブプロセス出力をPythonで非ブロック化する

subprocess.Popen()を作成してstdoutをキャプチャした後、p.communicate()を呼び出しても構いませんが、サブプロセスが終了するまでブロックされます。

私はsubprocess.check_output()などと考えても構いませんが、それもブロックされます。

私は何かを始めることができますし、次に他のものを行い、次にサブプロセスが終了していることを確認してください。

私はこれを達成するには、2つのかなり複雑な方法を考えることができます。

  1. その後、終了後、私はそのファイルからの出力を読み取ることができ、出力をファイルにリダイレクトします。
  2. サブプロセスのstdoutから常にデータを読み込み、バッファに追加するハンドラスレッド(!)を実装して起動します。

私の場合、最初のファイルとディスクI/Oは本当に好きではありません。 2つ目はかなりの実装です。

私はまだ考えられなかった簡単な方法、または私がまだ見つけなかったライブラリのすぐに使用される解決策があるかもしれないと思います。

+0

のようなものを試してみてください。あなたは例が必要ですか? –

答えて

1

スレッドでcheck_outputを呼び出すと何が問題になりますか? stdoutバッファがあるので、あなたがデッドロックを取得し、他の出力が小さい場合にのみが動作すること:1がp = subprocess.Popen(cmd,stdout=subprocess.PIPE)を使用するように誘惑することができ

import threading,subprocess 

output = "" 

def f(): 
    global output 
    output = subprocess.check_output("ls") # ["cmd","/c","dir"] for windows 


t = threading.Thread(target=f) 
t.start() 
print('Started') 
t.join() 
print(output) 

ノートでは、p.poll()がするのを待つ= Noneをし、その後p.stdoutを読み取ろう!あなたはそれを随時読まなければなりません。

p.stdout.readline()を使用すると、処理が正常に印刷されない場合でもブロックされます。アプリケーションが常に出力に出力する場合は、非ブロッキングと見なすことができ、解決策は受け入れられます。

+0

複数のプロセスを並行して起動する必要があります。彼らはどの順序で仕上げるのか分かりませんが、彼らはすべて出力を生み出しています。 1つが終了するたびに、私は出力を収集してすぐに使用したいと思います。あなたのスレッドのアプローチでは、私はスレッドの束(のいずれか)を待つ必要があります。私はそれをキューを使ってやると思います。しかし、それは私にとってはかなり複雑に思えます。また、サブプロセスを持つために、メインプロセスのスレッドを追加すると、構造が倍増するように聞こえます。私はむしろ一時ファイルのアプローチに行くと思います。 – Alfe

+0

関連:https://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in​​-python?rq = 1 –

0

あなたが望むのは、バッファされていないstdoutストリームです。 これを使用すると、処理が完了するのを待たずにプロセスの出力をキャプチャすることができます。 subprocess.Popen()関数とパラメータstdout=subprocess.PIPEでこれを達成できます。

は、「プロセスのスレッドで」アプローチは、その複雑ではありません。この

proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) 

line = proc.stdout.readline() 
while line: 
    print line 
    line = proc.stdout.readline() 
+0

私はこれらのいくつかを並行して持つ必要があり、どれがどれほど速く、いつ終了するかは分かりません。しかし、サブプロセスが終了するとすぐに、サブプロセスの出力を使用したいと思います。 – Alfe

関連する問題