subprocess.Popen
本質的にブロックしていません。あなたはまだ使用することができproc.stdin.write()
ますproc.stdout.read()
; 唯一の問題は、パイプがいっぱいになると、片側がブロックされたり、デッドロック[1]が発生したりするリスクがあることです。サブプロセスが少量のデータの読み取りまたは書き込みのみを行うことがわかっている場合は、それについて心配する必要はありません。
だからあなたはすることができます:
proc = subprocess.Popen(['perl', 'somescript.pl'], stdout=subprocess.PIPE)
buf = StringIO()
CHUNKSIZE = 1024 # how much to read at a time
while True:
# do whatever other time-consuming work you want here, including monitoring
# other processes...
# this keeps the pipe from filling up
buf.write(proc.stdout.read(CHUNKSIZE))
proc.poll()
if proc.returncode is not None:
# process has finished running
buf.write(proc.stdout.read())
print "return code is", proc.returncode
print "output is", buf.getvalue()
break
より大きなアプリでは、これをイベントループやreactorなどで発生するようにスケジュールできます。
[1] OSは、一度に非常に多くのデータをパイプに収めることしかできません。サブプロセスとして実行cat
し、そのstdinに大量のデータを書き込むとします。 cat
データがいっぱいになるまでそのデータを独自のstdoutに書き込み、その後、プログラムがstdoutからデータを読み取り、パイプを空にするまでブロックします。しかし、あなたのプログラムはまだstdinに書き込んでcat
いて、それから読み取っていないので、パイプもいっぱいになります。両方のプロセスが書き込みのブロックでスタックし、もう一方が読み取るのを待ちますが、これは決して起こりません。