2013-04-08 8 views
11

親プロセスの終了時に終了しないPython 2.7マルチプロセスプロセスがあります。私はそれが親の死に終了するように強制するデーモンのフラグを設定しました。ドキュメントは次のように述べています。マルチプロセスデーモンが親出口で終了しない

"プロセスが終了すると、デーモンのすべての子プロセスを終了しようとします。"

p = Process(target=_serverLaunchHelper, args=args) 
p.daemon = True 
print p.daemon # prints True 
p.start() 

私はkillコマンドを経由して親プロセスを終了するとデーモンは(ブロック次回の実行上のポート)生きているままにして実行されています。子プロセスはSimpleHttpServerを起動し、何もせずにserve_foreverを呼び出しています。私の推測では、ドキュメントの "試行"部分は、ブロッキングサーバープロセスがプロセスの停止を止めていることを意味し、結果としてプロセスが孤立してしまいます。私は子供が別のスレッドにサービスをプッシュし、親プロセスIDの変更をメインスレッドでチェックさせることができますが、これはデーモンの機能を複製するだけのコードのようです。

デーモンフラグが説明どおりに機能しない理由について誰かが洞察していますか?これはwindows8 64ビットとubuntu12 32ビットvmで繰り返すことができます。

Aは、処理機能のバージョンを煮詰め以下の通りです:

def _serverLaunchHelper(port) 
    httpd = SocketServer.TCPServer(("", port), Handler) 
    httpd.serve_forever() 

答えて

9

プロセスが終了すると、それはその鬼神のすべての子プロセスを終了させようとします。

キーワードは「試行」です。また、「出る」。

プラットフォームおよび実装によっては、デーモン子プロセスを終了させる唯一の方法は、明示的に行うことです。親プロセスが正常に終了すると、明示的に処理する機会が得られますので、すべて正常です。しかし、親プロセスが突然終了した場合、それは終了しません。あなたはthe sourceを見れば特にCPythonのために

は、鬼神のプロセスを終了することは非鬼神のプロセスに参加すると同じように処理されます:atexit機能でactive_children()を歩いて。したがって、あなたのデーモンは、あなたのatexitハンドラが実行される場合に限り、殺されます。そして、そのモジュールのドキュメントが言うように:

注:プログラムはPython内部で致命的なエラーが検出されたパイソン、によって処理されない信号によって殺されたときに、このモジュールを介して登録された関数が呼び出されていない場合、またはをos._exit()が呼び出されます。

親をどのように殺しているかによって、突然終了を傍受するシグナルハンドラを追加することで回避できます。 POSIXではSIGKILLが傍受できないため、kill -9 $PARENTPIDの場合、これはオプションではありません。

もう1つの方法は、親プロセスだけでなくプロセスグループを強制終了することです。例えば、あなたの親がPID 12345を持っているなら、linuxのkill -- -12345がそれを殺すでしょう。

+3

申し訳ありませんが、本当に親が死んだときに子供が辞めることを本当に保証したいのであれば、両親が消えていくのを見るために子供のプロセスにロジックをプログラムする必要があります。明確かつ迅速な答えをありがとう! – Pyrce

関連する問題