fork () y cómo se entregan las señales a los procesos

13

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?

Neil Locketz
fuente

Respuestas:

20

¿Por qué no lo probamos y vemos? Aquí hay un programa trivial que utiliza signal(3)para atrapar SIGINTtanto 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_trapy parent_trapfueron ejecutados cuando presioné Ctrl- C.

Hay una larga discusión sobre las interacciones entre forky 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:

  • Una señal generada manualmente y enviada a un proceso individual (quizás con kill) se entregará solo a ese proceso, independientemente de si es el padre o el hijo.
  • El orden en que se ejecutan los manejadores de señal entre procesos no está definido, por lo que no puede confiar en ejecutar primero.
  • Si no define un controlador de interrupciones (o ignora explícitamente la señal), ambos procesos simplemente saldrían con un SIGINTcódigo (el comportamiento predeterminado).
  • Si uno maneja la señal de manera no fatal y el otro no, el que no tiene el controlador morirá y el otro continuará.
Michael Homer
fuente
Supongo que los proyectiles también pueden interferir de manera interesante Si es una señal de que pueden atrapar, ¿podría enviarlo a sus hijos? (Y luego está SIGHUP) (Todo esto podría significar que si bien el sistema operativo no envía las señales, un proceso secundario podría no verse afectado por una señal al padre ...)
Gert van den Berg,