0

基本的に、このコードはパイプから読み取り、ブロックせずに常に出力を出力します...コード全体は次のとおりです。

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)
4

1 に答える 1

0

開発バージョン (3.2) では、それは非常に簡単です。

from tornado.web import RequestHandler,asynchronous
from tornado.process import Subprocess

class home(RequestHandler):
  @asynchrounous
  def get(self):
    seld.sp=Subprocess('date && sleep 5 && date',shell=True,stdout=Subprocess.STREAM)
    self.sp.set_exit_callback(self.next)
  def next(self,s):
    self.sp.stdout.read_until_close(self.finish)

application = ...
于 2013-12-05T11:08:29.000 に答える