Sinais para comunicação entre processos Linux
Introdução: Introdução: Breve introdução:
O mecanismo de sinal é um método de transferência de mensagens entre processos.O sinal é chamado de sinal de interrupção suave, que é usado para notificar o processo de um evento assíncrono. Os processos podem enviar sinais de interrupção suave uns aos outros por meio da eliminação da chamada do sistema; o kernel também pode enviar sinais ao processo devido a eventos internos para notificar o processo de que um evento ocorreu.
O processo que recebe o sinal possui diferentes métodos de processamento para vários sinais. Os métodos de processamento podem ser divididos em três categorias:
1. Semelhante aos manipuladores de interrupção, o processo pode especificar uma função de processamento para o sinal que precisa ser processado, e a função cuidará dela.
2. Ignore um determinado sinal e não faça nada no sinal, como se nunca tivesse acontecido.
3. O processamento do sinal retém o valor padrão do sistema.Esta operação padrão, a operação padrão para a maioria dos sinais é terminar o processo.
Terminologia básica do sinal Terminologia básica do sinal Letra número de grupos apresentam técnica Linguagem
- A ação real de processamento de sinal é chamada de entrega de sinal (entrega)
- O estado entre a geração e a entrega do sinal é denominado sinal pendente (Pendente).
- O processo pode escolher bloquear (bloquear) um sinal.
- O sinal bloqueado permanecerá no estado pendente quando for gerado, e a ação de entrega não será realizada até que o processo desbloqueie o sinal.
O ciclo de vida de um processo No processo de periferia da vida verde de
Quando um sinal SIGXXX é enviado para o processo de destino, o kernel do Linux recebe o sinal gerado e, em seguida, registra um registro no descritor de processo do processo de destino: o sinal SIGXXX é recebido, mas não foi entregue ao processo de destino neste período de tempo , O sinal está em um estado pendente, é chamado de sinal pendente sinal pendenteSem decisão carta nenhuma . O kernel entrega o sinal para o processo e o processo suspende o fluxo atual de controle e, em vez disso, executa a função de processamento do sinal.Este é o ciclo de vida completo de um sinal.
Classificação do sinal Classificação do sinal Canal número da sub- classe
不可靠信号:信号值在[1,31]之间的所有信号,被称为不可靠信号;也称非实时信号。对于不可靠信号,内核不一定能递送给目标进程,信号可能会丢失。
可靠信号:在[SIGRTMIN, SIGRTMAX]之间的信号被称为可靠信号;也称为实时信号。可靠信号时为了解决不可靠信号的丢失问题而产生的,Linux内核保证可靠信号能够递送给目标进程而不会丢失。
Características de diferentes tipos de sinais:
-
Para sinais não confiáveis, o kernel usa um bitmap (ou seja, um campo de sinal de interrupção suave no desempenho da tabela de processo, cada bit no campo corresponde a um sinal) para registrar se o sinal está em um estado suspenso. Se um sinal não confiável for recebido e o kernel descobrir que o sinal já está pendente, ele simplesmente descartará o sinal. Portanto, se um sinal não confiável for enviado, o sinal pode ser perdido, ou seja, o número de vezes que o kernel entrega ao processo de destino pode ser menor que o número de vezes que o sinal é enviado.
-
Para sinais confiáveis, há uma fila dentro do kernel para manter. Se um sinal confiável for recebido, o kernel irá travar o sinal na fila correspondente, então ele não será descartado. A rigor, o kernel também possui um limite superior, e o número de sinais pendentes não pode ser aumentado indefinidamente, caso contrário consome recursos do kernel, portanto, só se pode dizer que dentro de uma determinada faixa, os sinais confiáveis não serão descartados.
Para simplificar, os sinais não confiáveis são gerados várias vezes antes de serem entregues e apenas contados uma vez, enquanto os sinais confiáveis são gerados várias vezes antes de serem entregues e podem ser colocados em uma fila, por sua vez
Realização concreta do Linux de sinais não confiáveis Realização concreta do Linux de sinais não confiáveis L I n- U X para não ser contra o número do canal do corpo da ferramenta real agora
Para sinais não confiáveis (sinais em tempo não real), cada sinal tem dois bits de flag para indicar bloco e pendente, e um ponteiro de função para indicar ações de processamento.
Cada sinal possui um flag pendente de apenas um bit, que não é 0 ou 1. Não registra quantas vezes o sinal é gerado, e o flag de bloqueio também é representado desta forma. Portanto, os sinalizadores pendentes e bloqueados podem ser armazenados com o mesmo tipo de dados sigset_t, que é chamado de conjunto de sinais.
Este tipo pode representar o status "válido" ou "inválido" de cada sinal. O significado de "válido" e "inválido" no conjunto de sinais bloqueados é se o sinal está bloqueado e "válido" e "inválido" no conjunto de sinais pendente. O significado é se o sinal está pendente.
O tipo sigsett usa um bit para cada sinal para indicar o estado "válido" ou "inválido", e como armazenar esses bits dentro desse tipo depende da implementação do sistema operacional.
Observe que bloquear e ignorar são diferentes, contanto que o sinal seja bloqueado, ele não será entregue e ignorar é uma ação de processamento opcional após a entrega
Mais uma coisa a ser observada: Mais uma coisa a ser observada: Também há um ponto de necessidades a estadia destina a ser : um fluxo principal e um sinal de controle em resposta a diferentes funções usando espaço de pilha, e chamando a relação chamado não existe entre eles, dois fluxo de controle independente
funções relacionadas:
- função de sinal
#include <signal.h>
void (*signal(int signum, void (*handler)(int)))(int);
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
- função de matar
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
Usado para enviar qualquer sinal para qualquer processo ou grupo de processos
pid> 0: envia o sinal sig para o processo cujo número de processo é pid
pid = 0: o sinal sig será enviado para todos os processos no grupo de processos do processo atual
pid = -1: sinal sig será enviado para todos os processos exceto o processo 1 e ele próprio
pid <-1: o sinal sig será enviado para todos os processos pertencentes ao grupo de processos -pid
Se o parâmetro sig for 0, nenhum sinal será enviado
- função de pausa
#include <unistd.h>
int pause(void);
A função de pausa coloca o processo em hibernação até receber um sinal.
A chamada sempre retorna -1 e define o código de erro para EINTR (um sinal é recebido)
Se a ação de processamento de sinal for encerrar o processo, o processo será encerrado e a função de pausa não terá chance de retornar; se a ação de processamento de sinal for ignorada, o processo continuará em um estado suspenso e a pausa não retornará; se a ação de processamento de sinal for capturar, ela será chamada Após a função de processamento de sinal, pause retorna -1 e errno é definido como EINTR, então pause tem apenas um valor de retorno de erro. O código de erro EINTR significa "interrompido por sinal"
- função de alarme
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
A função é acertar um cronômetro, quando o cronômetro expirar enviará um sinal para o processo
alarme organiza o kernel para enviar um sinal SIGALRM para o processo de chamada após os segundos especificados
Uma configuração após o alarme irá cancelar a configuração anterior
Nota: o alarme só é definido para enviar um sinal uma vez, se desejar enviar várias vezes, você deve usar a chamada de alarme várias vezes
- função setitimer / getitimer
#include <sys/time.h>
int getitimer(int which, struct itimerval *value);
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue);
Setitimer é usado para definir o cronômetro, getitimer é usado para obter o status do cronômetro.
A chamada do sistema fornece três cronômetros para o processo, cada um dos quais tem seu próprio domínio de cronometragem exclusivo. Quando qualquer um deles chega, ele envia um sinal correspondente para o processo. , E faça o cronômetro reiniciar.
Três cronômetros são especificados pelo parâmetro que:
TIMER_REAL: Tempo real, quando o tempo atinge o envio do sinal SIGALRM
TIMER_VIRTUAL: o tempo é apenas quando o processo é executado, quando o tempo atinge o envio SIGVTALRM
TIMER_PROF:
- função de aumento
#include <signal.h>
int raise( int signal );
A função de aumento é usada para enviar um sinal para você
Inacabado. . .
referência: