Você não pode confiar que todos os sinais enviados serão entregues. Por exemplo, o kernel do linux "coalesce" o SIGCHLD se um processo demorar muito no tratamento do SIGCHLD a partir de um processo filho encerrado.
Para responder a outra parte da sua pergunta, os sinais são "enfileirados" dentro do kernel se um número de sinais diferentes chegar em um intervalo muito curto.
Você deve usar sigaction()
para configurar o manipulador de sinal com o sa_sigaction
membro de siginfo_t
, configurando o sa_mask
membro do siginfo_t
argumento com cuidado. Eu acho que isso significa mascarar todos os sinais "assíncronos", pelo menos. De acordo com a página de manual do Linux sigaction()
, você também irá mascarar o sinal que está sendo tratado. Acho que você deve definir o sa_flags
membro como SA_SIGINFO, mas não me lembro por que tenho essa superstição. Acredito que isso fará com que seu processo seja um manipulador de sinal que permaneça definido sem condições de corrida e que não seja interrompido pela maioria dos outros sinais.
Escreva sua função de tratamento de sinal com muito, muito cuidado. Basicamente, apenas defina uma variável global para indicar que um sinal foi capturado e o restante do processo lide com a ação desejada para esse sinal. Os sinais serão mascarados pelo menor tempo possível.
Além disso, você desejará testar seu código de manipulação de sinais com muito cuidado. Coloque-o em um pequeno processo de teste e envie o maior número possível de sinais SIGUSR1 e SIGUSR2, talvez de 2 ou 3 programas de envio de sinal para fins especiais. Misture alguns outros sinais também, depois de ter certeza de que seu código pode lidar com SIGUSR1 e SIGUSR2 de maneira rápida e correta. Prepare-se para depuração difícil.
Se você estiver usando linux e somente linux, pode pensar em usar signalfd()
para criar um descritor de arquivo que possa ser select()
pesquisado para receber esses sinais. O uso signalfd()
pode facilitar a depuração.
signal(2)
sugere enfaticamente que você evite essa confusão usandosigaction(2)
.