Sinal
Um sinal é um evento que é gerado para notificar um processo ou tópico que alguma situação importante chegou. Quando um processo ou tópico recebe um sinal, o processo ou o tópico interrompe o que está fazendo e toma alguma ação. O sinal pode ser útil para a comunicação entre processos.
Sinais padrão
Os sinais são definidos no arquivo de cabeçalho sinal.h Como uma macro constante. O nome do sinal começou com um "sig" e seguido por uma breve descrição do sinal. Então, todo sinal tem um valor numérico único. Seu programa deve sempre usar o nome dos sinais, não o número dos sinais. O motivo é que o número do sinal pode diferir de acordo com o sistema, mas o significado dos nomes será padrão.
A macro Nsig é o número total de sinal definido. O valor de Nsig é maior que o número total de sinal definido (todos os números de sinal são alocados consecutivamente).
A seguir estão os sinais padrão:
Nome do sinal | Descrição |
Sighup | Aperte o processo. O sinal de suspiro é usado para relatar a desconexão do terminal do usuário, possivelmente porque uma conexão remota é perdida ou desliga. |
Sigint | Interromper o processo. Quando o usuário digita o caractere INTR (normalmente Ctrl + C), o sinal SIGINT é enviado. |
Sigquit | Saia do processo. Quando o usuário digita o caractere de abandono (normalmente Ctrl + \), o sinal sigquit é enviado. |
Sigill | Instrução ilegal. Quando é feita uma tentativa de executar lixo ou instrução privilegiada, o sinal sigill é gerado. Além disso, Sigill pode ser gerado quando a pilha transbordar ou quando o sistema tiver problemas para executar um manipulador de sinal. |
Sigtrap | Armadilha de rastreamento. Uma instrução de ponto de interrupção e outras instruções de armadilha gerarão o sinal Sigtrap. O depurador usa este sinal. |
Sigabrt | Abortar. O sinal Sigabrt é gerado quando a função abort () é chamada. Este sinal indica um erro detectado pelo próprio programa e relatado pela chamada de função abort (). |
Sigfpe | Exceção de ponto flutuante. Quando ocorreu um erro aritmético fatal, o sinal SIGFPE é gerado. |
SIGUSR1 e SIGUSR2 | Os sinais SIGUSR1 e SIGUSR2 podem ser usados como você deseja. É útil escrever um manipulador de sinal para eles no programa que recebe o sinal de comunicação simples entre processos. |
Ação padrão dos sinais
Cada sinal tem uma ação padrão, um dos seguintes:
Prazo: O processo terá rescisão.
Essencial: O processo será encerrado e produzirá um arquivo de despejo principal.
IGN: O processo irá ignorar o sinal.
Parar: O processo vai parar.
Cont O processo continuará de ser parado.
A ação padrão pode ser alterada usando a função de manipulador. A ação padrão de algum sinal não pode ser alterada. Sigkill e Sigabrt A ação padrão do sinal não pode ser alterada ou ignorada.
Manuseio de sinal
Se um processo recebe um sinal, o processo tem uma escolha de ação para esse tipo de sinal. O processo pode ignorar o sinal, especificar uma função de manipulador ou aceitar a ação padrão para esse tipo de sinal.
Podemos lidar com o sinal usando sinal ou sigacção função. Aqui vemos como o mais simples sinal() A função é usada para lidar com sinais.
int signal () (int signum, void (*func) (int))O sinal() vai ligar para o functão função se o processo receber um sinal Signum. O sinal() Retorna um ponteiro para funcionar functão se for bem -sucedido ou retornar um erro para errar e -1 caso contrário.
O functão O ponteiro pode ter três valores:
Exemplo de manipulador de sinal básico
#incluirNa captura de tela da saída do exemplo1.C, podemos ver que na função principal o loop infinito está executando. Quando o usuário digitou Ctrl+C, a execução da função principal parou e a função manipuladora do sinal é invocada. Após a conclusão da função do manipulador, a execução da função principal retomada. Quando o tipo de usuário digitou Ctrl+\, o processo é interrompido.
Ignorar sinais de exemplo
#incluirAqui a função manipuladora é registrada para Sig_ign () função para ignorar a ação do sinal. Então, quando o usuário digitou Ctrl+C, Sigint o sinal está gerando, mas a ação é ignorada.
Exemplo de manipulador de sinal de Reregister
#incluirNa captura de tela da saída do exemplo3.C, podemos ver que, quando o usuário digitou pela primeira vez Ctrl+C, a função Handler é invocada. Na função do manipulador, o manipulador de sinal registra para Sig_dfl Para ação padrão do sinal. Quando o usuário digitou Ctrl+C pela segunda vez, o processo é encerrado, que é a ação padrão de Sigint sinal.
Sinais de envio:
Um processo também pode enviar sinais explicitamente para si ou para outro processo. função Raise () e Kill () pode ser usada para enviar sinais. Ambas as funções são declaradas em sinal.H Arquivo de cabeçalho.
int raise (int signum)A função Raise () usada para enviar sinal Signum para o processo de chamada (por si só). Ele retorna zero se for bem -sucedido e um valor diferente de zero se falhar.
int matar (pid_t pid, int signum)A função de morte usada para enviar um sinal Signum para um processo ou grupo de processo especificado por PID.
Exemplo de manipulador de sinal SIGUSR1
#incluirAqui, o processo envia o sinal SIGUSR1 para si mesmo usando a função Raise ().
Aumente o programa de exemplo de Kill
#incluirAqui, o processo envia SIGUSR1 sinalizando para si mesmo usando matar() função. getpid () é usado para obter o ID do processo de si mesmo.
No próximo exemplo, veremos como os processos de pais e filhos se comunicam (comunicação entre processos) usando matar() e função de sinal.
Comunicação dos filhos de pais com sinais
#incluirAqui, garfo() A função cria processos infantis e retorna zero ao processo da criança e ID do processo para a criança ao processo dos pais. Então, o PID foi verificado para decidir o processo pai e filho. No processo dos pais, ele está dormindo por 1 segundo para que o processo infantil possa registrar a função do manipulador de sinal e aguardar o sinal do pai. Após 1 segundo processo pai, envie SIGUSR1 sinalize para o processo infantil e aguarde o sinal de resposta da criança. No processo infantil, primeiro está esperando o sinal do pai e quando o sinal é recebido, a função do manipulador é invocada. Da função do manipulador, o processo filho envia outro SIGUSR1 sinal para o pai. Aqui getppid () A função é usada para obter o ID do processo pai.
Conclusão
O sinal no Linux é um grande tópico. Neste artigo, vimos como lidar com o sinal do muito básico e também obter um conhecimento de como o sinal gera, como um processo pode enviar sinal para si e outros processos, como o sinal pode ser usado para comunicação entre processos.