fork () e como os sinais são entregues aos processos

13

O programa que escrevi em C fork () está fora de um processo filho. Nenhum processo será encerrado. Se eu iniciar o programa a partir da linha de comando e pressionar control-c, quais processos receberão o sinal de interrupção?

Neil Locketz
fonte

Respostas:

20

Por que não experimentamos e vemos? Aqui está um programa trivial usando signal(3)para interceptar SIGINTo processo pai e filho e imprimir uma mensagem identificando o processo quando ele chegar.

#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;
}

Vamos chamar assim test.c. Agora podemos executá-lo:

$ gcc test.c
$ ./a.out
^CCaught signal in CHILD.
They got back together!

Os sinais de interrupção gerados no terminal são entregues ao grupo de processos ativo, que inclui aqui pai e filho . Você pode ver que ambos child_trape parent_trapforam executados quando eu pressionei Ctrl- C.

Há uma longa discussão sobre interações forke sinais no POSIX . A parte mais importante disso aqui é que:

Um sinal enviado ao grupo de processos após o fork () deve ser entregue ao pai e ao filho.

Eles também observam que alguns sistemas podem não se comportar exatamente da maneira correta, principalmente quando o sinal chega muito perto da hora do sinal fork(). Descobrir se você está em um desses sistemas provavelmente exigirá a leitura do código ou muita sorte, porque as interações são muito improváveis ​​em cada tentativa individual.

Outros pontos úteis são os seguintes:

  • Um sinal gerado manualmente e enviado para um processo individual (talvez com kill) será entregue apenas a esse processo, independentemente de ser o pai ou o filho.
  • A ordem em que os manipuladores de sinal são executados entre os processos não está definida, portanto você não pode confiar em executar primeiro.
  • Se você não definir um manipulador de interrupções (ou ignorar explicitamente o sinal), ambos os processos serão encerrados com um SIGINTcódigo (o comportamento padrão).
  • Se um manipula o sinal de maneira não fatal e o outro não, aquele sem o manipulador morrerá e o outro continuará.
Michael Homer
fonte
Suponho que conchas também podem interferir de maneiras interessantes? Se é um sinal que eles podem capturar, pode enviá-lo para seus filhos? (E depois há SIGHUP) (Tudo isso pode significar que, enquanto o OS não envia os sinais, um processo filho pode não ser afetado por um sinal para o pai ...)
Gert van den Berg