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.pyとfoobar.pyの要点を見つけることができます。実行python parser.py
して出力ファイルを確認するだけです。
編集: djangoデーモン化メソッドにはいくつかのヒントがあります