Tratamento de sinais C ++

Os sinais são as interrupções entregues a um processo pelo sistema operacional que podem encerrar um programa prematuramente. Você pode gerar interrupções pressionando Ctrl + C em um sistema UNIX, LINUX, Mac OS X ou Windows.

Existem sinais que não podem ser captados pelo programa, mas há uma lista de sinais a seguir que você pode capturar em seu programa e pode executar as ações apropriadas com base no sinal. Esses sinais são definidos no arquivo de cabeçalho C ++ <csignal>.

Sr. Não Sinal e descrição
1

SIGABRT

Encerramento anormal do programa, como uma chamada para abort.

2

SIGFPE

Uma operação aritmética errada, como uma divisão por zero ou uma operação que resulta em estouro.

3

SIGILL

Detecção de uma instrução ilegal.

4

SIGINT

Recebimento de um sinal de atenção interativo.

5

SIGSEGV

Um acesso inválido ao armazenamento.

6

SIGTERM

Uma solicitação de encerramento enviada ao programa.

A função signal ()

A biblioteca de tratamento de sinais C ++ fornece funções signalpara capturar eventos inesperados. A seguir está a sintaxe da função signal () -

void (*signal (int sig, void (*func)(int)))(int);

Mantendo a simplicidade, esta função recebe dois argumentos: o primeiro argumento como um inteiro que representa o número do sinal e o segundo argumento como um ponteiro para a função de tratamento do sinal.

Vamos escrever um programa C ++ simples onde capturaremos o sinal SIGINT usando a função signal (). Qualquer sinal que você deseja capturar em seu programa, você deve registrar esse sinal usandosignalfunção e associá-la a um manipulador de sinal. Examine o seguinte exemplo -

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum ) {
   cout << "Interrupt signal (" << signum << ") received.\n";

   // cleanup and close up stuff here  
   // terminate program  

   exit(signum);  
}

int main () {
   // register signal SIGINT and signal handler  
   signal(SIGINT, signalHandler);  

   while(1) {
      cout << "Going to sleep...." << endl;
      sleep(1);
   }

   return 0;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado -

Going to sleep....
Going to sleep....
Going to sleep....

Agora, pressione Ctrl + c para interromper o programa e você verá que seu programa irá capturar o sinal e sairá imprimindo algo como segue -

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.

A função raise ()

Você pode gerar sinais por função raise(), que recebe um número de sinal inteiro como argumento e tem a seguinte sintaxe.

int raise (signal sig);

Aqui, sigé o número do sinal para enviar qualquer um dos sinais: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP. A seguir está o exemplo em que levantamos um sinal internamente usando a função raise () da seguinte maneira -

#include <iostream>
#include <csignal>

using namespace std;

void signalHandler( int signum ) {
   cout << "Interrupt signal (" << signum << ") received.\n";

   // cleanup and close up stuff here  
   // terminate program  

   exit(signum);  
}

int main () {
   int i = 0;
   // register signal SIGINT and signal handler  
   signal(SIGINT, signalHandler);  

   while(++i) {
      cout << "Going to sleep...." << endl;
      if( i == 3 ) {
         raise( SIGINT);
      }
      sleep(1);
   }

   return 0;
}

Quando o código acima é compilado e executado, ele produz o seguinte resultado e sairia automaticamente -

Going to sleep....
Going to sleep....
Going to sleep....
Interrupt signal (2) received.