2011-07-11 29 views
2

、私は手動で停止するかもしれない生まれつきのシェルプロセスを持っています。あるいは、それが気に入ったらそれ自身を終了させるかもしれません。いつもポーリングするのではなく、完了したという通知を受け取ることはできますか?Popen終了時に信号を受信する方法はありますか?

class Foo(object): 

    def __init__(self): 
    self.running = False 

    def start(self): 
    import os 
    from subprocess import Popen, PIPE 
    self.proc = Popen(['foo'], stdout=PIPE, shell=True, preexec_fn=os.setsid) 
    self.running = True 

    def stop(self): 
    if not self.running: 
     print 'already stopped' 
    else: 
     import os, signal 
     os.killpg(self.proc.pid, signal.SIGINT) 
     self.on_complete() 

    def on_complete(self): 
    self.running = False 

構築物は、多かれ少なかれ上記と同様である。私の問題は、自分の割り込みではなく、プロセスが正常に終了した場合、self.runningTrueのままであるため、その属性をクラスの他のロジックに依存することはできません。

通常の終了の場合にはon_completeと呼ばれる簡単な方法がありますか、これは最初は愚かな設計ですか?

答えて

3

SIGCHLDのハンドラをインストールできるはずです。しかし、ドキュメントを注意深く読んでください。そのシグナルに関心を登録することによって、シグナルハンドラ内の子プロセスを処理することを約束しています。実行中のすべての子プロセスがシグナルハンドラによって処理されてからエラーになるまで、サブプロセス自体にあるwaitがブロックされます。これには、system()Popenの独自のサブプロセスクリーンアップが含まれます。 (たとえば、Popen.communicate() throws OSError: "[Errno 10] No child processes"を参照してください)