基本的に、このコードはパイプから読み取り、ブロックせずに常に出力を出力します...コード全体は次のとおりです。
1)最初のスクリプト:
if __name__ == '__main__':
for i in range(5):
print str(i)+'\n',
sys.stdout.flush()
time.sleep(1)
2) 2 番目のスクリプト:
def log_worker(stdout):
while True:
output = non_block_read(stdout).strip()
if output:
print output
def non_block_read(output):
''' even in a thread, a normal read with block until the buffer is full '''
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 ''
if __name__ == '__main__':
mysql_process = subprocess.Popen(['python','-u', 'flush.py'], stdin=sys.stdin,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
thread = Thread(target=log_worker, args=[mysql_process.stdout])
thread.daemon = True
thread.start()
mysql_process.wait()
thread.join(timeout=1)
なぜそれがそのように機能するのか知りたいです:
1)スレッドを完全に取り除き、メインでlog_workerを呼び出すだけで、すべてを1つずつ出力しますが、問題は完了後に終了せずにハングすることです。そして、ここでスレッドが正確に使用されて終了するか、より正確には、何かを印刷し終えるとスレッドが死ぬことをどこかで読んだので、なぜそのように機能するのですか? ここではどのスレッドが正確にどのように機能しますか?
2)スレッドを保持し、mysql_process.wait() と thread.join を削除すると、何も出力されません ....なぜですか? Popen.wait は、その子プロセスが終了するためのものであると読みました。returncode 属性を設定して返します。ここでの子プロセスとは何ですか?なぜ/どのように子 O_O ですか?
3) thread.join(timeout=1) のみを削除すると、終了しますが、エラーが発生しますException in thread Thread-1 (most likely raised during interpreter shutdown):
。なんで ?ここで .join が果たす役割。
4) non_block_read function で使用される関数のドキュメントを読みましたが、まだ混乱しています。さて、彼らがファイル記述子を取り、それを非ブロッキングに設定することは明らかです。私が混乱しているのは、これらすべての関数を何に使用できるかということです。つまり、ファイルではそれを理解していますが、なぜstdout O_Oでそれを使用するのでしょうか? ファイルではなく、ストリームです ~~ ?
これはすべて、トルネード スクリプトで subprocess.Popen を使用してスクリプトを実行し、ブロックせずにクライアント/自分自身に常に出力を送信するために行うものです。この出力をスレッドから取得して、tornadio2のself.sendに常に挿入できるようにします...
def on_message(self, message):
# list = subprocess.Popen([r"ls", "-l"], stdout=subprocess.PIPE)
# list_stdout = list.communicate()[0]
for i in range(1,10):
time.sleep(1)
self.send(i)