2011-12-13 38 views
4

Imに問題があります...誰でもこのコードがwhileループでハングする理由を知っていますか?ループは、stdoutの最後の行をキャッチしていないようです。python popen.stdout.readline()がハングします

readline()に遭遇したときにカーソルが点滅するだけでスクリプトがハングします。なぜか分からない。誰もがすべての

JON

+1

ここの推測に行くが、私はp.stdout.read *は()は常になることを発見しました

import fcntl import os def nonBlockRead(output): fd = output.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) try: return output.read() except: return '' working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) stdout = '' while working_file.poll() is None: stdout += nonBlockRead(working_file.stdout) # we can probably save some time and just print it instead... #print(stdout) stdout = stdout.splitlines() for line in stdout: print(line) 

編集ブロッキング呼び出しであり、戻すデータがない場合はブロックされます。ノンブロッキングの読みはあなたを助けるかもしれません。 –

+0

大規模な馬鹿のように聞こえる危険にさらされていますが、ノンブロッキングの読書で感謝します。:) –

+0

読むべきデータがない場合、read()がハングします。それは一度戻ってくるデータ(またはそれのうちの十分なもの)があると戻ってくるだけです。ノンブロックの読み込みではデータがすぐに返され、存在しない場合はデータは返されません。したがって、ハングしません(または、ブロッキングコールではありません:_nonblocking call_)。 –

答えて

4

はノンブロッキングをやっていいくつかの光

感謝を流すことができ、あなたを助けて読みますか?

import fcntl 
import os 

def nonBlockReadline(output): 
    fd = output.fileno() 
    fl = fcntl.fcntl(fd, fcntl.F_GETFL) 
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) 
    try: 
     return output.readline() 
    except: 
     return '' 

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) 

line = nonBlockReadline(working_file.stdout) 
working_file.stdout.flush() 
while working_file != "" : 
    print(line) 
    line = nonBlockReadline(working_file.stdout) 
    working_file.stdout.flush() 

私はあなたがしようとしていることを正確にはわかりませんが、これはうまくいくでしょうか?一度に1行だけを読み込むのではなく、すべてのデータを読み込むだけです。それは私にはもう少し読みやすいです。ご使用のケースのために、より適している必要があり、一般化スクリプト:

import fcntl 
import os 

def nonBlockRead(output): 
    fd = output.fileno() 
    fl = fcntl.fcntl(fd, fcntl.F_GETFL) 
    fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) 
    try: 
     return output.read() 
    except: 
     return '' 

working_file = subprocess.Popen(["/pyRoot/iAmACrashyProgram"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) 

while working_file.poll() is None: 
    stdout = nonBlockRead(working_file.stdout) 

    # make sure it returned data 
    if stdout: 
     # process data 
     working_file.stdin.write(something) 
+0

あなたはA努力。私はこれがうまくいきたい(ありがとう、私はこれからかなり学んだ) – FakeRainBrigand

+0

うわー、病気を試してみる、私は完全にそれを理解していると言う:)私は実際に外部プロセスを起動し、その出力に基づいて、いくつかの値をstdinに書き込みます。私はちょっと深いところから私は、私が何をしようとするよりもエレガントな方法がなければならないように感じる、あなたは住んでいるとあなたが学ぶ:) –

+0

あなたのユースケースに基づいて、うまくいけば、これはまだ助けになるでしょう。あなたの問題に適したスクリプトを追加しましたが、それでもノンブロッキングです(しかし 'working_file.stdout.readline()'で簡単に修正できます)。 –

関連する問題