Domine o Tratamento de Sinais em C++: Gestão Segura de Interrupções e Término Limpo de Programas
Sinais são interrupções entregues a um processo pelo sistema operacional que podem encerrar um programa prematuramente. Você pode gerar interrupções pressionando Ctrl+C em sistemas UNIX, Linux, macOS ou Windows.
Sinais Capturáveis em C++
Existem sinais que não podem ser capturados pelo programa, mas a seguir está a lista de sinais que você pode interceptar no seu código e tomar as ações apropriadas. Esses sinais são definidos no cabeçalho C++ <csignal>.
| Nº | Sinal e Descrição |
|---|---|
| 1 | SIGABRT Término anormal do programa, como uma chamada a abort. |
| 2 | SIGFPE Operação aritmética errônea, como divisão por zero ou overflow. |
| 3 | SIGILL Detecção de uma instrução ilegal. |
| 4 | SIGINT Recebimento de um sinal de atenção interativa (ex.: Ctrl+C). |
| 5 | SIGSEGV Acesso inválido à memória (segmentation fault). |
| 6 | SIGTERM Solicitação de término enviada ao programa. |
A Função signal()
A biblioteca de tratamento de sinais do C++ fornece a função signal para capturar eventos inesperados. A sintaxe é:
void (*signal (int sig, void (*func)(int)))(int);
Simplificando, esta função recebe dois argumentos: o primeiro é um inteiro representando o número do sinal, e o segundo é um ponteiro para a função manipuladora de sinais.
Vamos escrever um programa simples em C++ que captura o sinal SIGINT usando a função signal(). Qualquer sinal que você queira capturar deve ser registrado com a função signal e associado a um manipulador (handler). Veja o exemplo:
#include <iostream>
#include <csignal>
#include <unistd.h>
using namespace std;
void signalHandler(int signum) {
cout << "Sinal de interrupção (" << signum << ") recebido.\n";
// limpeza e fechamento de recursos aqui
exit(signum);
}
int main() {
// registra o sinal SIGINT e seu manipulador
signal(SIGINT, signalHandler);
while (true) {
cout << "Indo dormir...." << endl;
sleep(1);
}
return 0;
}
Quando o código acima é compilado e executado, ele produz o seguinte resultado:
Indo dormir....
Indo dormir....
Indo dormir....
Agora, pressione Ctrl+C para interromper o programa. Você verá que o programa captura o sinal e encerra imprimindo algo como:
Indo dormir....
Indo dormir....
Indo dormir....
Sinal de interrupção (2) recebido.
A Função raise()
Você pode gerar sinais programaticamente usando a função raise(), que recebe um número de sinal inteiro como argumento e tem a seguinte sintaxe:
int raise(int sig);
Aqui, sig é o número do sinal a ser enviado: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP. Veja o exemplo onde geramos um sinal internamente usando raise():
#include <iostream>
#include <csignal>
#include <unistd.h>
using namespace std;
void signalHandler(int signum) {
cout << "Sinal de interrupção (" << signum << ") recebido.\n";
exit(signum);
}
int main() {
int i = 0;
signal(SIGINT, signalHandler);
while (++i) {
cout << "Indo dormir...." << endl;
if (i == 3) {
raise(SIGINT);
}
sleep(1);
}
return 0;
}
Ao compilar e executar, o programa produz a seguinte saída e encerra automaticamente:
Indo dormir....
Indo dormir....
Indo dormir....
Sinal de interrupção (2) recebido.
Com isso, você aprende a lidar com sinais de forma segura, garantindo que seu programa possa realizar limpeza adequada antes de terminar, seja por interrupção do usuário ou por condições de erro internas.
Linguagem C
- Entendendo Tipos de Dados em C++: Fundamentos, Modificadores e Boas Práticas
- Dominando Operadores em C++: Guia Completo com Exemplos Práticos
- Comentários em C++: Boas Práticas para Código Legível e Manutenível
- Dominando Templates de Classe em C++: Um Guia Prático
- Manipulação de Arquivos em C: Dominando I/O com fopen, fprintf, fread e fseek
- Dominando Tratamento de Exceções em C++: Exemplos Práticos com Try, Catch, Throw
- Dominando Tratamento de Erros em C: Boas Práticas e Técnicas
- Linguagem de Programação C++: Visão Geral e Principais Características
- Constantes e Literais em C++: Tipos, Sintaxe e Boas Práticas
- Guia Completo de Operadores em C++: Tipos, Uso e Boas Práticas