wasabi tipos tiene sushi sabor que palitos palillos jengibre frio día con como comer come chinos calentar anterior c debugging fork

c - tipos - que sabor tiene el sushi



Por qué tenedor() dos veces (5)

En Linux, un daemon se crea típicamente bifurcando dos veces con el proceso intermedio que sale después de bifurcar al nieto. Esto tiene el efecto de huérfano el proceso nieto. Como resultado, se vuelve responsabilidad del sistema operativo limpiar después si termina. La razón tiene que ver con lo que se conoce como procesos zombie que continúan viviendo y consumiendo recursos después de salir porque su padre, que normalmente sería responsable de la limpieza, también ha muerto.

Esta pregunta ya tiene una respuesta aquí:

Nagios me permite configurar child_processes_fork_twice=<0/1> .

La documentación dice

Esta opción determina si Nagios tenedor () niño procesa o no dos veces cuando ejecuta comprobaciones de host y servicio. Por defecto, Nagios fork () s dos veces. Sin embargo, si la opción use_large_installation_tweaks está habilitada, solo tejerá () una vez.

Por lo que sé, fork() generará un nuevo proceso hijo. ¿Por qué querría hacer eso dos veces?


También de la documentación ,

Normalmente, Nagios tecleará () dos veces cuando ejecute comprobaciones de host y servicio. Esto se hace para (1) asegurar un alto nivel de resistencia contra plugins que fallan y segfault y (2) hacer que el sistema operativo se encargue de limpiar el proceso de nieta una vez que se cierra.


Unix Faq. De programación §1.6.2:

1.6.2 ¿Cómo evito que ocurran?

waitpid() asegurarse de que su proceso principal llama a wait() (o waitpid() , wait3() , etc.) para cada proceso hijo que finaliza; o, en algunos sistemas, puede indicarle al sistema que no está interesado en los estados de salida infantil.

Otro enfoque es fork() dos veces , y hacer que el proceso secundario inmediato salga de inmediato. Esto hace que el proceso nieto quede huérfano, por lo que el proceso init es responsable de limpiarlo. Para que el código haga esto, consulte la función fork2() en la sección de ejemplos.

Para ignorar los estados de salida secundarios, debe hacer lo siguiente (consulte las páginas de manual de su sistema para ver si esto funciona):

struct sigaction sa; sa.sa_handler = SIG_IGN; #ifdef SA_NOCLDWAIT sa.sa_flags = SA_NOCLDWAIT; #else sa.sa_flags = 0; #endif sigemptyset(&sa.sa_mask); sigaction(SIGCHLD, &sa, NULL);

Si esto tiene éxito, entonces las funciones wait() no pueden funcionar; si se llama a alguno de ellos, esperarán hasta que todos los procesos secundarios hayan finalizado, luego devolverán el error con errno == ECHILD .

La otra técnica es captar la señal SIGCHLD y hacer que el manejador de señales llame a waitpid() o wait3() . Vea la sección de ejemplos para un programa completo.


Este código demuestra cómo usar el método de doble fork para permitir que init adopte el proceso de nieto, sin riesgo de procesos zombies.

#include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <sys/types.h> int main() { pid_t p1 = fork(); if (p1 != 0) { printf("p1 process id is %d", getpid()); wait(); system("ps"); } else { pid_t p2 = fork(); int pid = getpid(); if (p2 != 0) { printf("p2 process id is %d", pid); } else { printf("p3 process id is %d", pid); } exit(0); } }

El padre fork el nuevo proceso secundario y luego wait a que termine. El niño fork un proceso de nieta y luego saldrá exit(0) .

En este caso, el nieto no hace nada más que exit(0) , pero podría hacer lo que le gustaría que hiciera el proceso del daemon. El nieto puede vivir mucho tiempo y será recuperado por el proceso de init , cuando esté completo.


De acuerdo, ahora primero que todo: ¿qué es un proceso zombie?

Es un proceso que está muerto, pero su padre estaba ocupado haciendo otro trabajo, por lo tanto, no pudo recopilar el estado de salida del niño.

En algunos casos, el niño corre durante un tiempo muy largo, el padre no puede esperar tanto tiempo y continuará con su trabajo (tenga en cuenta que el padre no muere, sino que continúa sus tareas restantes pero no se preocupa por el niño). )

De esta forma, se crea un proceso zombie.


Ahora, vayamos al grano. ¿Cómo funciona el bifurcar dos veces aquí?

Lo importante a tener en cuenta es que el nieto hace el trabajo que el proceso principal quiere que su hijo haga.

Ahora, la primera vez que se llama una bifurcación, el primer niño simplemente se bifurca y sale. De esta forma, el padre no tiene que esperar durante mucho tiempo para recopilar el estado de salida del niño (ya que el único trabajo del niño es crear otro niño y salir). Entonces, el primer niño no se convierte en un zombie.

En cuanto al nieto, su padre ya murió. Por lo tanto, el nieto será adoptado por el proceso init , que siempre recopila el estado de salida de todos sus procesos secundarios. Entonces, ahora el padre no tiene que esperar mucho tiempo, y no se creará ningún proceso zombie.


Hay otras formas de evitar un proceso zombie; esta es solo una técnica común.


¡Espero que esto ayude!