# Sinal (ciência da computação)

Em ciência da computação, um sinal (signal em inglês) é uma forma limitada de comunicação entre processos utilizada em sistemas Unix e outros sistemas operacionais compatíveis com o padrão POSIX. Essencialmente, um sinal é uma notificação assíncrona enviada a processos com o objetivo de notificar a ocorrência de um evento. Quando um sinal é enviado a um processo, o sistema operacional interrompe o seu fluxo normal de execução. A execução pode ser interrompida em qualquer operação que não seja atômica. Um processo pode registrar uma rotina de tratamento de sinal (signal handler em inglês) para tratar um determinado sinal, se não for desejado que a rotina padrão para este sinal seja executada.

## Enviando sinais

Determinadas combinações de teclas, ao serem pressionadas no terminal de controle de um processo em execução, fazem com que o sistema envie determinados sinais a este processo:
* Ctrl-C (DEL em versões antigas do Unix) envia um sinal INT (SIGINT); normalmente causa o término do processo.
* Ctrl-Z envia um sinal TSTP (SIGTSTP); normalmente causa a suspensão da execução do processo.
* Ctrl-\ envia um sinal QUIT (SIGQUIT); normalmente causa o término da execução do processo e a geração de um core dump.
* A chamada de sistema kill(2) envia um sinal ao processo, se o usuário tiver permissão para tal. De maneira parecida, o comando kill do Unix permite que um "usuário" envie sinais a um processo. A chamada de sistema raise envia um sinal para o processo "corrente".
* As exceções causadas por divisão por zero ou violação de segmento de memória geram sinais (SIGFPE e SIGSEGV, respectivamente, gerando um core dump).
* O núcleo do sistema operacional pode gerar sinais a fim de notificar processos de um evento. Por exemplo, o sinal SIGPIPE é gerado quando um processo escreve em uma canalização que foi fechado pelo leitor; normalmente causa o término do processo, o que é conveniente na construção de encadeamento.

## Tratando sinais

Rotinas de tratamento de sinais podem ser instaladas através da chamada de sistema signal. Se uma rotina de tratamento não é instalada para um determinado sinal, a rotina padrão é utilizada. No caso de existir uma rotina de tratamento, o sinal é interceptado e a rotina de tratamento é invocada. O processo também pode especificar dois comportamentos padrão, sem a criação de uma rotina de tratamento: ignorar o sinal (SIG_IGN) e utilizar a rotina de tratamento padrão (default handler) (SIG_DFL). Existem dois sinais que não podem ser interceptados e tratados: SIGKILL e SIGSTOP.
O tratamento de sinais é vulnerável à condições de competição. Devido à natureza assíncrona dos sinais, um outro sinal, possivelmente do mesmo tipo, pode ser enviado a um mesmo processo durante a execução de uma rotina de tratamento de sinal. A chamada de sistema sigprocmask pode ser utilizada para bloquear ou desbloquear o envio de sinais.
Os sinais podem causar a interrupção de uma chamada de sistema em progresso, deixando para a aplicação, a responsabilidade de gerenciar um reinicio não transparente.

## Relacionamento com exceções

A execução de um processo pode resultar na geração de uma exceção de hardware (em uma divisão por zero, por exemplo). Em sistemas do tipo Unix, este evento muda automaticamente o contexto do processador iniciando a execução de uma rotina de núcleo para tratamento de exceção. No caso de exceções de falta de página, por exemplo, o núcleo tem informação suficiente para tratar completamente o evento e continuar a execução do processo. Porém, em outros tipos de exceção, o núcleo não consegue preceder de maneira inteligente e tem que transferir o tratamento da exceção para um processo de tratamento de falha. Esta transferência é realizada através do mecanismo de sinais, no qual o núcleo envia ao processo, um sinal correspondente a exceção ocorrida. Por exemplo, se um processo tenta dividir um número por zero em uma CPU de arquitetura x86, uma exceção divisão por zero seria gerada e faria com que o núcleo enviasse um sinal SIGFPE para o processo. De maneira similar, se um processo tentasse acessar uma região de memória fora do seu espaço de endereçamento virtual, o núcleo notificaria esta violação ao processo através do sinal SIGSEGV. O mapeamento exato entre exceções e nomes de sinais é obviamente dependente da CPU, pois os tipos de exceções variam conforme a arquitetura utilizada.

## Lista de sinais

A especificação Single Unix Specification apresenta os seguintes sinais (definidos no arquivo de cabeçalho da linguagem C de nome <signal.h>):
    SIGABRT - processo abortado
    SIGALRM - sinal levantado por alarme
    SIGBUS - erro de barramento: "access to undefined portion of memory object"
    SIGCHLD - processo filho terminado, parado (*ou continuado)
    SIGCONT - continuar se parado
    SIGFPE - exceção de ponto flutuante: "erroneous arithmetic operation"
    SIGHUP - término de comunicação com terminal
    SIGILL - instrução ilegal
    SIGINT - interrupção
    SIGKILL - kill
    SIGPIPE - escrita em uma canalização em que nenhum processo lê
    SIGQUIT - quit
    SIGSEGV - falha de segmentação
    SIGSTOP - parada temporária na execução
    SIGTERM - término
    SIGTSTP - término enviado por um terminal de controle
    SIGTTIN - tentativa de leitura ("in") de um processo em "background"
    SIGTTOU - tentativa de escrita ("out") de um processo em "background"
    SIGUSR1 - definida pelo usuário 1
    SIGUSR2 - definida pelo usuário 2
    *SIGPOLL - evento pesquisável
    *SIGPROF - temporizador expirado
    *SIGSYS - chamada de sistema incorreta invocada
    *SIGTRAP - trap
    SIGURG - dados urgentes disponíveis em um socket
    *SIGVTALRM - sinal disparado por um temporizador de tempo virtual: "virtual timer expired"
    *SIGXCPU - limite de tempo da CPU excedido
    *SIGXFSZ - limite de tamanho de arquivo excedido
Nota: As seções marcadas por um asterisco denotam extensões ao X/Open System Interfaces (XSI). As palavras entre aspas são as utilizadas na especifiação Single Unix Specification.