2

Popenで長いfoobar.pyプロセスを実行し、その出力をマルチプロセッシングプロセスで解析する必要があります。

私の問題は、パーサーが終了するのを待てないことがあるため、 multiprocessing デーモン プロパティを使用してパーサーをデーモン化する必要があることです。パーサーがデーモン的ではないデーモン的な方法の両方で使用できるようにする必要があります。ドキュメントには、デーモンプロセスが子プロセスを作成することは許可されていないとも書かれています。その場合、パーサーが fork される前に Popen プロセスを実行します (以下の start メソッドを参照)。

class Parser(multiprocessing.Process):
    def __init__(self, daemon, output):
        super(Parser, self).__init__()
        self.daemon = daemon
        self.output = output

    def start(self):
        if self.daemon:
            self.launchFoobar() # Foobar is launched before forking
        super(Parser, self).start()

    def run(self):
        if not self.daemon:
            self.launchFoobar() # Foobar is launched after forking
        self.parseFoobar()

    def launchFoobar(self):
        self.process = subprocess.Popen(["python", "foobar.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    def parseFoobar(self):
        with open(self.output, "w+") as f:
            for line in iter(self.process.stdout):
                f.write(line)
                f.flush()
        self.process.wait()

ここで、foobar.pyが数秒待って何かを出力し、 parseFoobarメソッドが出力をファイルに出力するとします。私の場合、両方の関数はこれよりもはるかに複雑です。

実行は正常に機能し、 sync.txtParser(daemon=False, "sync.txt").start()にいくつかの出力があります。しかし、実行してもasync.txtには何も生成されず、ファイルが作成されているため、行でブロックされているように見えますが、空です。Parser(daemon=True, "async.txt")for line in iter(self.process.stdout):

うまくいかないのはなぜですか?どうすれば修正できますか?

テスト用にparser.pyfoobar.pyの要点を見つけることができます。実行python parser.pyして出力ファイルを確認するだけです。

編集: djangoデーモン化メソッドにはいくつかのヒントがあります

4

1 に答える 1

3

あなたは実際にあなたが望む正確な動作を得ています。デーモンを作成してProcessから、ほとんどすぐにメイン プロセスを終了します。Processこれでは、デーモンが終了する前に実際に実行foobar.pyして出力を解析するのに十分な時間がありません。プログラムの最後にへの呼び出しを追加すると、それが書き込まasync.join()れることがわかります。async.txt

また、デーモン内から呼び出すこともできます。プロセスがサブプロセスを作成できないという注意事項は、実際には子オブジェクトの作成について話しているだけです。デーモンが子オブジェクトを適切にクリーンアップできないため、制限がありますが、親が終了しても、によって開かれたプロセスはクリーンアップされません。subprocess.Popenmultiprocessing.Processdaemonmultiprocessing.ProcessProcessProcesssubprocess.Popen

于 2014-09-30T13:45:54.717 に答える