child process não herda os sinais pendentes do pai depois de uma chamada de sistema fork, por quê?

3

Alguém poderia me dizer por que os sinais pendentes não são herdados pelo processo filho? Por outro lado, o processo filho herda os manipuladores de sinal e máscara de sinal do pai, por que isso é feito? Um exemplo seria muito útil, então eu poderia entender o conceito muito melhor.

    
por Gilles 28.09.2013 / 07:40

1 resposta

4

Could anybody please tell me the reason to why pending signals are not inherited by the child process?

Os sinais vêm em dois tipos, síncrono e assíncrono. Os síncronos começam com o kernel em resposta a algo que o processo fez - por exemplo, o sempre popular SIGSEGV. Sinais assíncronos geralmente vêm de outros processos e, como o nome indica, chegam a algum ponto arbitrário. Um sinal "pendente" é aquele que ainda não foi entregue ou que foi bloqueado temporariamente pelo processo de recebimento. Considere alguns cenários pendentes e por que seria inadequado para a criança herdá-los.

Síncrono, não entregue: Vamos pegar o exemplo de um SIGSEGV que está pendente porque o pai cometeu uma violação de acesso - algo que, na verdade, não acontece ou não acontece por tempo suficiente para realmente considerá-lo como "pendente" de uma perspectiva de espaço de usuário, mas por causa do argumento - então é o pai que cometeu a violação, não o filho. Se a criança fizer algo semelhante (o que provavelmente aconteceria), ela receberá seu próprio sinal. Se por acaso não, então não deveria receber um que estava pendente para o pai.

Assíncrono, não entregue: Neste caso, realmente não pode ser significativo se o sinal estava pendente pela duração do fork e então entregue ao pai, já que o sinal é assíncrono - não pode ser intencionado interromper o processo em um determinado ponto, é como um telefonema; o interlocutor não está pretendendo pegá-lo enquanto você ainda está sentado em sua cadeira porque o chamador não pode saber disso. O ponto da ligação é apenas comunicar algo para você. Além disso, os sinais são endereçados a um processo específico e o filho é um processo separado com seu próprio PID. Se eu enviar um sinal para processar 1001, não espero que ele também processe 1002.

Bloqueado (síncrono ou assíncrono): Neste caso, o sinal é deixado intencionalmente pelo processo, então ele teve a oportunidade de desbloqueá-lo antes do fork (mas não o fez). Como é sabido que tais sinais não serão herdados pela criança, este cenário ocorre por design . Por exemplo, um servidor recebe um sinal e, por qualquer motivo, decide bloqueá-lo temporariamente enquanto responde a uma solicitação recebida - pselect() conseguirá isso, eu acho - e para lidar com a solicitação que ele cria um filho. Então ele lida com o sinal pendente.

On the other hand, the child process inherits the signal handlers and signal mask from the parent, why is this done?

Isso parece ser essencial para o conceito de um fork: o filho é uma cópia do pai. Manipuladores de sinal são apenas funções regulares com um propósito especial. Mais uma vez, como isso é conhecido, pode ser explorado por design ou, pelo contrário, compensado. É bastante fácil remover um manipulador se você não quiser mais usá-lo.

    
por 28.09.2013 / 13:08