Grupo de multiprocesamiento Python dentro del proceso del daemon

Abrí una pregunta para este problema y no obtuve una respuesta lo suficientemente exhaustiva para resolver el problema (probablemente debido a una falta de rigor en la explicación de mis problemas, que es lo que estoy tratando de corregir): Proceso de Zombie en el daemon multiproceso de Python

Estoy tratando de implementar un demonio de Python que usa un grupo de trabajadores para ejecutar comandos usando Popen . He tomado prestado el demonio básico de http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/

Solo he cambiado los daemonize init , daemonize (o igualmente start ) y stop . Aquí están los cambios al método init :

 def __init__(self, pidfile): #, stdin='/dev/null', stdout='STDOUT', stderr='STDOUT'): #self.stdin = stdin #self.stdout = stdout #self.stderr = stderr self.pidfile = pidfile self.pool = Pool(processes=4) 

No estoy configurando stdin, stdout y stderr para poder depurar el código con sentencias de impresión. Además, he intentado mover este grupo a algunos lugares, pero este es el único lugar que no produce excepciones.

Aquí están los cambios al método de daemonize :

     def daemonize(self): ... # redirect standard file descriptors #sys.stdout.flush() #sys.stderr.flush() #si = open(self.stdin, 'r') #so = open(self.stdout, 'a+') #se = open(self.stderr, 'a+', 0) #os.dup2(si.fileno(), sys.stdin.fileno()) #os.dup2(so.fileno(), sys.stdout.fileno()) #os.dup2(se.fileno(), sys.stderr.fileno()) print self.pool ... 

    Lo mismo, no estoy redireccionando io para poder depurar. La impresión aquí se utiliza para que pueda comprobar la ubicación de los grupos.

    Y el método de stop cambia:

     def stop(self): ... # Try killing the daemon process try: print self.pool print "closing pool" self.pool.close() print "joining pool" self.pool.join() print "set pool to None" self.pool = None while 1: print "kill process" os.kill(pid, SIGTERM) ... 

    Aquí la idea es que no solo tengo que matar el proceso sino también limpiar la piscina. El self.pool = None es solo un bash aleatorio de resolver los problemas que no funcionaron. Al principio pensé que esto era un problema con los niños zombis que se estaba produciendo cuando tuve el self.pool.close() y self.pool.join() dentro del bucle while con el os.kill(pid, SIGTERM) . Esto es antes de que decidiera comenzar a buscar en la ubicación de la agrupación a través de print self.pool . Después de hacer esto, creo que las agrupaciones no son las mismas cuando se inicia el daemon y cuando se detiene. Aquí hay algunos resultados:

     me@pc:~/pyCode/jobQueue$ sudo ./jobQueue.py start  me@pc:~/pyCode/jobQueue$ sudo ./jobQueue.py stop  closing pool joining pool set pool to None kill process kill process ... [ stuck in infinite loop] 

    Las diferentes ubicaciones de los objetos me sugieren que no son el mismo grupo y que uno de ellos es probablemente el zombi.

    Después de CTRL+C , esto es lo que obtengo de ps aux|grep jobQueue :

     root 21161 0.0 0.0 50384 5220 ? Ss 22:59 0:00 /usr/bin/python ./jobQueue.py start root 21162 0.0 0.0 0 0 ? Z 22:59 0:00 [jobQueue.py]  me 21320 0.0 0.0 7624 940 pts/0 S+ 23:00 0:00 grep --color=auto jobQueue 

    He intentado mover el self.pool = Pool(processes=4) a un número de lugares diferentes. Si se mueve a los methods, start()' or daemonize () methods, print self.pool` lanzará una excepción que dice que es NoneType. Además, la ubicación parece cambiar el número de procesos zombie que aparecerán.

    Actualmente, no he agregado la funcionalidad para ejecutar nada a través de los trabajadores. Mi problema parece estar completamente relacionado con la configuración correcta del grupo de trabajadores. Apreciaría cualquier información que conduzca a resolver este problema o algún consejo sobre cómo crear un servicio de daemon que use un grupo de trabajadores para ejecutar una serie de comandos usando Popen . Como no he llegado tan lejos, no sé a qué retos me enfrento. Estoy pensando que podría necesitar escribir mi propia piscina, pero si hay un buen truco para hacer que la piscina funcione aquí, sería increíble.

    La solución es poner la self.pool = Pool(process=4) como la última línea del método de daemonize . De lo contrario, la piscina termina perdiéndose en algún lugar (tal vez en la fork ). A continuación, se puede acceder al grupo dentro del método de run que está sobrecargado por la aplicación que desea demonizar. Sin embargo, no se puede acceder a la agrupación en el método de detención y, de hacerlo, se producirían excepciones de tipo Ninguno. Creo que hay una solución más elegante, pero esto funciona y es todo lo que tengo por ahora. Si quiero que la stop falle cuando el grupo todavía está en acción, tendré que agregar una funcionalidad adicional para run y algún tipo de mensaje, pero actualmente no estoy preocupado por esto.