2010-12-04 12 views
12

Mi código de prueba esprocesos hijos mueren al matar a los padres si uno de ellos se detiene con SIGSTOP

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <unistd.h> 

int main() { 
    int c = fork(); 
    if (c == 0) while(1); 
    c = fork(); 
    if (c == 0) while(1); 
    c = fork(); 
    if (c == 0) while(1); 
    c = fork(); 
    if (c == 0) while(1); 
    while(1); 
} 

Así que tienen un padre y 4 niños. Cuando mato al padre, los niños están trabajando bien con init como padre. Pero si paro (con SIGSTOP) a uno de los niños y luego mato al padre, los niños también son asesinados. ¿Por qué esto es así?

+3

Su código es una muy buena manera de hacer café muy caliente usando su CPU ... Especialmente si tiene 4 núcleos o más ... –

+0

Sí, es :) Pero esto es solo para una prueba y cumple esto papel. – Ximik

+1

Gran pregunta ... fascinado de ver la respuesta. Sospecho que los grupos de procesos están involucrados, pero no estoy seguro de cómo. –

Respuesta

13

Aparentemente, si se detiene un proceso en el grupo de procesos, todos los procesos se señalan con SIGHUP y luego con SIGCONT cuando finaliza el líder del grupo de procesos. El controlador predeterminado para SIGHUP finaliza el proceso. Es el comportamiento esperado, como se documenta en, p.

http://www.win.tue.nl/~aeb/linux/lk/lk-10.html

Desde el enlace de arriba:

Si la terminación de un proceso hace que un grupo proceso para convertirse en huérfano, y algún miembro se detuvo, y luego todos son envió primero SIGHUP y luego SIGCONT.

La idea es que quizás el padre de el líder del grupo de procesos es un trabajo shell de control. (En la misma sesión pero un grupo de procesos diferente). Como mientras este padre esté activo, puede manejar la detención y el inicio de los miembros en el grupo de procesos. Cuando muere, puede que no haya nadie para continuar procesos detenidos. Por lo tanto, estos procesos detenidos se envían SIGHUP, por lo que que mueren a menos que detecten o los ignoren, y luego SIGCONT continúe hasta .

EDIT:

Por cierto, strace es una herramienta maravillosa para llegar al fondo de este tipo de cosas. Si conecta strace a uno de los procesos hijos, verá que SIGHUP se entrega solo si uno de ellos se detiene cuando el padre (es decir, el líder del grupo de procesos) fallece.

Debe cambiar el controlador de SIGHUP utilizando, p. Ej. sigaction (2) si desea que los procesos de los niños sobrevivan.

+0

Si inicia el programa de tal manera que no utiliza un nuevo grupo de procesos (por ejemplo, ejecutarlo con 'at' en lugar del shell), este comportamiento no se exhibe. Envié 'STOP' a un niño, maté al padre, y los niños seguían corriendo con esta configuración. –

+0

Por cierto, 'strace' habría sido una buena herramienta para observar lo que sucede. –

+0

@R ..: strace es lo que me puso en el camino correcto para esto ... – thkala

0

Los elementos secundarios pertenecen al mismo grupo de procesos que el proceso principal y, por lo tanto, se destruyen junto con el proceso principal.

Sugerencia: no utilice while(1); para suspender un proceso. Déjelo sleep indefinidamente.

+0

Aparentemente no es cierto en mi sistema. ¿Lo intentaste? – thkala

+0

@thkala Lo he intentado solo en Fedora y Archlinux. ¿Puedes decir, qué es tuyo distr? – Ximik

+0

@goreSplatter pero ¿por qué no se eliminan si no envío SIGSTOP? – Ximik

Cuestiones relacionadas