Programa que escribí en C fork () fuera de un proceso hijo. Ninguno de los procesos terminará. Si inicio el programa desde la línea de comando y presiono control-c, ¿qué proceso (s) recibirá la señal de interrupción?
¿Por qué no lo probamos y vemos? Aquí hay un programa trivial que utiliza signal(3)
para atrapar SIGINT
tanto el proceso principal como el secundario e imprimir un mensaje que identifica el proceso cuando llega.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void parent_trap(int sig) {fprintf(stderr, "They got back together!\n");}
void child_trap(int sig) {fprintf(stderr, "Caught signal in CHILD.\n");}
int main(int argc, char **argv) {
if (!fork()) {
signal(SIGINT, &child_trap);
sleep(1000);
exit(0);
}
signal(SIGINT, &parent_trap);
sleep(1000);
return 0;
}
Llamemos a eso test.c
. Ahora podemos ejecutarlo:
$ gcc test.c
$ ./a.out
^CCaught signal in CHILD.
They got back together!
Las señales de interrupción generadas en el terminal se entregan al grupo de proceso activo, que aquí incluye tanto padre como hijo . Puedes ver que ambos child_trap
y parent_trap
fueron ejecutados cuando presioné Ctrl- C.
Hay una larga discusión sobre las interacciones entre fork
y las señales en POSIX . La parte más importante aquí es que:
Una señal enviada al grupo de proceso después de la bifurcación () debe entregarse tanto al padre como al hijo.
También señalan que algunos sistemas pueden no comportarse exactamente de la manera correcta, en particular cuando la señal llega muy cerca del momento de la fork()
. Averiguar si estás en uno de esos sistemas probablemente requerirá leer el código o mucha suerte, porque las interacciones son muy poco probables en cada intento individual.
Otros puntos útiles son que:
kill
) se entregará solo a ese proceso, independientemente de si es el padre o el hijo.SIGINT
código (el comportamiento predeterminado).