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.