Programuję, że napisałem w C fork () poza procesem potomnym. Żaden proces nie zostanie zakończony. Jeśli uruchomię program z wiersza poleceń i naciśniesz control-c, który proces (procesy) otrzyma sygnał przerwania?
Dlaczego tego nie wypróbujemy i nie zobaczymy? Oto trywialny program wykorzystujący signal(3)
pułapkę SIGINT
zarówno w procesie nadrzędnym, jak i podrzędnym oraz do wydrukowania komunikatu identyfikującego proces po jego nadejściu.
#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;
}
Nazwijmy to test.c
. Teraz możemy go uruchomić:
$ gcc test.c
$ ./a.out
^CCaught signal in CHILD.
They got back together!
Sygnały przerwań generowane w terminalu są dostarczane do aktywnej grupy procesów, która obejmuje tutaj zarówno element nadrzędny, jak i podrzędny . Możesz to zobaczyć child_trap
i parent_trap
zostały wykonane, gdy nacisnąłem Ctrl- C.
Jest długi omówienie interakcji pomiędzy fork
i sygnałów POSIX . Najbardziej materialną częścią tego jest to, że:
Sygnał wysyłany do grupy procesów po rozwidleniu () powinien być dostarczany zarówno do rodzica, jak i dziecka.
Zauważają również, że niektóre systemy mogą nie zachowywać się dokładnie w odpowiedni sposób, w szczególności gdy sygnał zbliża się bardzo blisko czasu fork()
. Ustalenie, czy korzystasz z jednego z tych systemów, prawdopodobnie będzie wymagać przeczytania kodu lub dużo szczęścia, ponieważ interakcje są znikome w każdej próbie.
Inne przydatne punkty to:
kill
) zostanie dostarczony tylko do tego procesu, niezależnie od tego, czy jest to rodzic, czy dziecko.SIGINT
kodem (zachowanie domyślne).