El demonio multiproceso no termina en la salida principal

Tengo un proceso de multiprocesamiento de Python 2.7 que no se cerrará en la salida del proceso principal. He establecido la bandera del demonio que debería forzarla a salir de la muerte del padre. Los documentos afirman que:

“Cuando un proceso sale, intenta terminar todos sus procesos secundarios demoníacos”.

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

Cuando finalizo el proceso principal a través de un comando kill, el daemon se queda vivo y en ejecución (lo que bloquea el puerto en la siguiente ejecución). El proceso secundario es iniciar SimpleHttpServer y llamar a serve_forever sin hacer nada más. Mi conjetura es que la parte de “bashs” de los documentos significa que el proceso del servidor de locking está deteniendo la muerte del proceso y, como resultado, deja el proceso huérfano. Podría hacer que el niño empuje la porción a otro Thread y que el hilo principal compruebe los cambios de la ID del proceso principal, pero esto parece una gran cantidad de código para replicar la funcionalidad del daemon.

¿Alguien tiene una idea de por qué la bandera del demonio no funciona como se describe? Esto es repetible en windows8 64 bit y ubuntu12 32 bit vm.

A continuación se muestra una versión resumida de la función de proceso:

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

Cuando un proceso sale, intenta terminar todos sus procesos secundarios demoníacos.

La palabra clave aquí es “bashs”. Además, “salidas”.

Dependiendo de su plataforma e implementación, puede ser que la única manera de terminar los procesos secundarios demoníacos sea hacerlo explícitamente. Si el proceso principal sale normalmente, tiene la oportunidad de hacerlo explícitamente, por lo que todo está bien. Pero si el proceso padre termina abruptamente, no lo hace.

En particular, para CPython, si observa la fuente , los procesos demoníacos de finalización se manejan de la misma manera que uniendo procesos no demoníacos: recorriendo active_children() en una función atexit . Por lo tanto, sus demonios serán asesinados si y solo si sus manejadores atexit se ejecutan. Y, como dicen los documentos de ese módulo:

Nota: las funciones registradas a través de este módulo no se llaman cuando el progtwig es eliminado por una señal no manejada por Python, cuando se detecta un error interno fatal de Python, o cuando se llama a os._exit() .

Dependiendo de cómo esté matando al padre, puede solucionar esto agregando un controlador de señal para interceptar la terminación abrupta. Pero es posible que no: por ejemplo, en POSIX, SIGKILL no es capaz de interceptar, por lo que si kill -9 $PARENTPID , esta no es una opción.

Otra opción es eliminar el grupo de procesos, en lugar de solo el proceso principal. Por ejemplo, si su padre tiene PID 12345, kill -- -12345 en linux lo matará a él ya todos sus hijos (suponiendo que no haya hecho nada especial).