4

UbuntuLinuxマシンで2つのPythonスクリプトを実行しています。1つ目はすべての出力をstdoutに送信し、2つ目はstdinから読み取ります。それらは単純なパイプ、つまり次のようなもので接続されています。

./step1.py <some_args> | ./step2.py <some_other_args>

step2は、無限ループで入力行を読み取り、それらを処理します。

while True:
    try:
        l = sys.stdin.readline()
        # processing here

Step1は時々クラッシュします。それが起こったとき(常にかどうかはわかりませんが、少なくともいくつかの機会に)、step2はクラッシュ/停止する代わりに、手動で強制終了するまでCPUを100%使用し始めます。

なぜこれが起こっているのですか?パイプが壊れたときに停止するようにstep2をより堅牢にするにはどうすればよいですか?

ありがとう!

4

2 に答える 2

3

step1 が終了すると、例外をスローするステートメントの試行を含む while ループが発生します。したがって、例外をスローしているときに readline がブロックされないため、CPU の 100% を使用して継続的に試行して失敗します。

読み取りに時間遅延を追加するtime.sleepか、さらに良いことに、デッド パイプから読み取ろうとする代わりに、readline がスローするエラーに注意を払い、step1 が停止してプログラムを終了するときにスローされる特定のエラーをキャッチします。

おそらく、パイプが空のときにスリープ オペレーターが必要であり、パイプが終了したときに終了する必要がありますが、どの例外がスローされ、それぞれの場合にどのメッセージが表示されるかを判断するための演習として残します。このような状況では sleep オペレーターは必要ありませんが、無用な作業で CPU 使用率が高くなる可能性がある他の状況を避けることができます。

于 2012-09-10T17:19:06.860 に答える
3

特定のケースで無限ループに陥る理由を他の人がすでに説明しています。

2 番目の (読み取り) スクリプトでは、イディオムを使用できます。

for line in sys.stdin:
    process(line)

この方法では、無限ループに陥ることはありません。さらに、2 番目のスクリプトでキャッチしようとしている例外を実際に示していませんでしたが、「壊れたパイプ」エラーが発生することがあると思いますPython の壊れたパイプ (SIGPIPE)?

スキーム全体は次のようになります。

try:
    for line in sys.stdin:
        process(line)
except IOError, e:
    if e.errno == errno.EPIPE:
        # EPIPE error
    else:
        # Other error
于 2012-09-10T17:22:23.337 に答える