Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> Linguagem C

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

  1. Entendendo Tipos de Dados em C++: Fundamentos, Modificadores e Boas Práticas
  2. Dominando Operadores em C++: Guia Completo com Exemplos Práticos
  3. Comentários em C++: Boas Práticas para Código Legível e Manutenível
  4. Dominando Templates de Classe em C++: Um Guia Prático
  5. Manipulação de Arquivos em C: Dominando I/O com fopen, fprintf, fread e fseek
  6. Dominando Tratamento de Exceções em C++: Exemplos Práticos com Try, Catch, Throw
  7. Dominando Tratamento de Erros em C: Boas Práticas e Técnicas
  8. Linguagem de Programação C++: Visão Geral e Principais Características
  9. Constantes e Literais em C++: Tipos, Sintaxe e Boas Práticas
  10. Guia Completo de Operadores em C++: Tipos, Uso e Boas Práticas