¿Cómo puedo matar un proceso <defunct> cuyo padre es init?

27

La transmisión se cuelga intermitentemente en mi NAS. Si envío SIGTERM, no desaparece de la lista de procesos y <defunct>aparece una etiqueta al lado. Si envío un SIGKILL, todavía no desaparece y no puedo terminar el padre porque el padre es init. La única forma en que puedo deshacerme del proceso y reiniciar la transmisión es reiniciando.

Me doy cuenta de que lo mejor que puedo hacer es probar y reparar la Transmisión (y lo he intentado), pero soy un novato en la compilación y quería asegurarme de que mis torrents terminen antes de comenzar a jugar.

Andy E
fuente
3
Nadie dice lo obvio ... ¡un proceso <defunct> propiedad de "init" debería ser imposible! ¡Esta es una situación muy extraña! ¿Estás seguro?
JoelFan
@JoelFan: Solo estaba buscando eso para asegurarme de no olvidar algo importante. Los zombis que son hijos de initdeberían desaparecer bastante rápido ya que initespera a los niños periódicamente como una de sus muchas tareas comunes ... ¿es <defunct>lo mismo que un zombi?
D.Shawley
1
no importa ... <defunct>es exactamente lo mismo que un zombie. initesperará a sus hijos para que esto nunca suceda en teoría. Me pregunto ¿qué ocurre si se envía un SIGCHLDa init?
D.Shawley
@JoelFan: sí, estoy seguro. El valor para PPID fue 1 (init), por lo que fue imposible SIGKILL el proceso.
Andy E
3
similar a unix.stackexchange.com/a/5648
tshepang

Respuestas:

35

No puedes matar un <defunct>proceso (también conocido como proceso zombie) ya que ya está muerto. El sistema mantiene procesos zombies para que el padre recopile el estado de salida. Si el padre no recopila el estado de salida, los procesos zombie permanecerán para siempre. La única forma de deshacerse de esos procesos zombies es matando al padre. Si el padre es init, solo puede reiniciar.

Los procesos de zombis casi no requieren recursos, por lo que no hay costo de rendimiento al permitir que permanezcan. Aunque tener procesos zombies alrededor generalmente significa que hay un error en algunos de sus programas. Init generalmente debe recoger a todos los niños. Si init tiene hijos zombis, entonces hay un error en init (o en otro caso, pero es un error).

http://en.wikipedia.org/wiki/Zombie_process

lesmana
fuente
99
initnunca puede tener hijos zombies. Del artículo de Wikipedia: Cuando un proceso pierde a su padre, init se convierte en su nuevo padre. Init ejecuta periódicamente la llamada al sistema de espera para cosechar zombies con init como padre. Una de initlas responsabilidades es cosechar huérfanos y zombies sin padres.
D.Shawley
14
@ D.Shawley: initaunque puede tener errores. El reemplazo de init runitha tenido un error que causa este problema.
camh
2
init puede tener hijos difuntos, tal vez debido a un error, pero puede. Porque estoy mirando uno ahora mismo.
studgeek
Existe este programa que ejecuté desde la terminal y entré en estado difunto. Como explicó @lesmana, cuando cerré la terminal (principal) el programa salió limpiamente.
mk ..
6

Cualquiera que intente arreglar el código fuente de la Transmisión C debería leer sobre el truco del "doble tenedor" para evitar zombis y manejadores de señales ... y cómo se puede usar como parte de una función inteligente de generación varódica (ver Generación en Unix ).

excerpt from: 
   "Spawning in Unix", http://lubutu.com/code/spawning-in-unix

Double fork
This trick lets you spawn processes whilst avoiding zombies, without 
installing any signal handler. The first process forks and waits for its 
child; the second process forks and immediately exits and is reaped;
the third process is adopted by init, and executes the desired program. 
All zombies accounted for, since init is always waiting.

if(fork() == 0) {
   if(fork() == 0) {
       execvp(file, argv);
       exit(EXIT_FAILURE);
   }
   exit(EXIT_SUCCESS);
}
wait(NULL);
nazar
fuente
1
La doble bifurcación evita los procesos de zombis al obligar al núcleo a establecer su padre en PID 1, que se supone que limpia zombies. Parece que la transmisión ya lo hace, ya que su padre ya está en el proceso 1.
Jander
1
Hay múltiples problemas aquí. # 1: solo los padres deben llamar exit(3); los niños deberían llamar en su _exit(2)lugar (de lo contrario, obtendrá múltiples descargas estándar, entre otros problemas). # 2: Eso execvp(3)podría usar a perror(3)si falla. # 3: Deberías usar en signal(SIGCHLD, SIG_IGN)lugar de todo este desastre.
Kevin