12

親プロセスの終了時に終了しない 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 で再現可能です。

プロセス関数の煮詰めたバージョンは次のとおりです。

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

1 に答える 1

11

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

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

プラットフォームと実装によっては、デーモンの子プロセスを終了させる唯一の方法は、明示的に終了することである場合があります。親プロセスが正常に終了すると、明示的に終了する機会が得られるため、すべて問題ありません。ただし、親プロセスが突然終了した場合は、そうではありません。

特に CPython の場合、 sourceを見ると、デーモン プロセスの終了は非デーモン プロセスへの参加と同じ方法で処理されます。つまりactive_children()atexit関数内を歩くことです。atexitしたがって、デーモンは、ハンドラーが実行された場合にのみ強制終了されます。そして、そのモジュールのドキュメントが言うように:

注: このモジュールを介して登録された関数は、Python によって処理されないシグナルによってプログラムが強制終了された場合、Python の致命的な内部エラーが検出された場合、または が呼び出された場合にos._exit()は呼び出されません。

親を殺す方法によっては、突然の終了をインターセプトするシグナル ハンドラーを追加することで、これを回避できる場合があります。しかし、そうではないかもしれません — たとえば、POSIX ではSIGKILL傍受できませkill -9 $PARENTPIDん。

別のオプションは、親プロセスだけでなく、プロセス グループを強制終了することです。たとえば、親が PID 12345 を持っている場合、kill -- -12345Linux では親とそのすべての子が殺されます (特別なことを何もしていないと仮定します)。

于 2013-04-08T20:21:32.203 に答える