そのようなp.stdoutを使用することはできません。「stdout全体」を要求した場合、これはプロセスの終了時(またはパイプバッファーの充填時、長時間かかる可能性があります)にのみ使用可能になります。
プロセスのstdoutから1行ずつ読み取る必要があります。
while True:
ln = p.stdout.readline()
if '' == ln:
break
m = re.search("Thread (?P<id>\d+)", ln);
if m:
# use m.group() to extract information
# e.g. m.group('id') will hold the 12345 from "Thread 12345"
stdoutをラインバッファリングに設定できれば(通常は可能な限り完全にバッファリングされます)、これも最適ですが、これは呼び出されたプログラム内からのみ実行できると思います。
ここで考慮すべき2つのバッファーがあります。1つはCプログラムの出力バッファです。これは、存在しない(バッファリングされていない出力)、ラインバッファリングされている、または完全にバッファリングされている可能性があります(1K、4K、または8Kがいくつかの可能なサイズです)。
プログラム内では、「printf()」が呼び出されます。出力は次のようになります。
- バッファリングされていない場合
- バッファに; 次に、行がバッファリングされている場合、バッファ内のすべての改行で終了する行が出力されます。
- バッファに; 次に、4Kバッファで完全にバッファリングされ、バッファが4Kよりもいっぱいの場合、最初の4Kが出力されます。
これで、出力がPythonのパイプに入ります。これも完全にバッファリングされる(stdout)か、ラインバッファリングされる(readline)可能性があります。したがって、出力は次のようになります。
- パイプラインに完全な改行で終了する行が1つあり、readlineを使用している場合は、Pythonプログラムのロジックに
- パイプラインに4K未満があり、「for ln in stdout」を使用している場合は、バッファに追加します。
この最後のケースでは、バッファーは4KチャンクでPythonロジックに送られます。
ここで、Pythonプログラムに毎秒1K文字の長さの1行を出力する行バッファーCプログラムを想像してみましょう(Cプログラムが完全にバッファーされている場合、実行できることはあまりありません!)
サイクルでstdoutを読み取ると、(forループ内で)次のようになります。
- t =0...何もありません
- t = 1 ...なし(バッファが50%いっぱいです)
- t = 2 ...なし(バッファが75%いっぱいです)
- t = 3...4行の出力
- t =4...何も..。
readlineを読むと、次のようになります。
- t = 0...1行
- t = 1...1行
- t = 2...1行
- t = 3...1行
例
ここでは、2秒間隔でローカルホストに3つのパケットを取得するために、「ping -c 3-i2127.0.0.1」を実行します。1回のpingの実行には約6秒かかります。pingからの出力を読み取り、タイムスタンプを出力します。pingの出力全体は、Pythonのフルバッファーに収まるほど小さいです。
#!/usr/bin/python
import subprocess
from time import gmtime, strftime
p = subprocess.Popen(["ping", "-c", "3", "-i", "2", "127.0.0.1"],
stdout=subprocess.PIPE)
for ln in p.stdout:
print strftime("%H:%M:%S", gmtime()) + " received " + ln
# Now I start the same process again, reading the input the other way.
p = subprocess.Popen(["ping", "-c", "3", "-i", "2", "127.0.0.1"],
stdout=subprocess.PIPE)
while True:
ln = p.stdout.readline()
if '' == ln:
break
print strftime("%H:%M:%S", gmtime()) + " received " + ln
Linuxボックスで受け取る出力は、予想どおりです。
(nothing for the first six seconds)
15:40:10 received PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
15:40:10 received 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.037 ms
15:40:10 received 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.034 ms
15:40:10 received 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.031 ms
15:40:10 received
15:40:10 received --- 127.0.0.1 ping statistics ---
15:40:10 received 3 packets transmitted, 3 received, 0% packet loss, time 3998ms
15:40:10 received rtt min/avg/max/mdev = 0.031/0.034/0.037/0.002 ms
15:40:10 received PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
15:40:10 received 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.041 ms
15:40:12 received 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.039 ms
15:40:14 received 64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.035 ms
15:40:14 received
15:40:14 received --- 127.0.0.1 ping statistics ---
15:40:14 received 3 packets transmitted, 3 received, 0% packet loss, time 3999ms
15:40:14 received rtt min/avg/max/mdev = 0.035/0.038/0.041/0.005 ms