Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> Lenguaje C

Dominar el manejo de señales en C++: Gestión segura de interrupciones y terminación limpia del programa

Las señales son interrupciones enviadas a un proceso por el sistema operativo que pueden terminar un programa prematuramente. Puedes generar interrupciones presionando Ctrl+C en sistemas UNIX, Linux, macOS o Windows.

Existen señales que no pueden ser capturadas por el programa, pero a continuación se muestra una lista de señales que sí puedes capturar en tu código y tomar las acciones apropiadas según la señal recibida. Estas señales están definidas en el archivo de cabecera de C++ <csignal>.

Nº Señal y descripción
1 SIGABRT
Terminación anormal del programa, como una llamada a abort.
2 SIGFPE
Operación aritmética errónea, como división por cero o desbordamiento.
3 SIGILL
Detección de una instrucción ilegal.
4 SIGINT
Recepción de una señal de atención interactiva (Ctrl+C).
5 SIGSEGV
Acceso inválido a almacenamiento (violación de segmento).
6 SIGTERM
Solicitud de terminación enviada al programa.

La función signal()

La biblioteca de manejo de señales de C++ proporciona la función signal para atrapar eventos inesperados. La sintaxis de la función signal() es:

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

Simplificando, esta función recibe dos argumentos: el primero es un entero que representa el número de señal, y el segundo es un puntero a la función manejadora de señales.

Veamos un programa simple en C++ donde capturamos la señal SIGINT usando la función signal(). Cualquier señal que quieras capturar en tu programa debe registrarse usando la función signal y asociarse con un manejador de señales. Examina el siguiente ejemplo:

#include <iostream>
#include <csignal>
#include <unistd.h>

using namespace std;

void signalHandler(int signum) {
    cout << "Señal de interrupción (" << signum << ") recibida.\n";
    // Limpieza y cierre de recursos aquí
    // Terminar programa
    exit(signum);
}

int main() {
    // Registrar señal SIGINT y su manejador
    signal(SIGINT, signalHandler);

    while(true) {
        cout << "Durmiendo...." << endl;
        sleep(1);
    }
    return 0;
}

Cuando el código anterior se compila y ejecuta, produce el siguiente resultado:

Durmiendo....
Durmiendo....
Durmiendo....

Ahora, presiona Ctrl+C para interrumpir el programa y verás que tu programa captura la señal y sale imprimiendo algo como sigue:

Durmiendo....
Durmiendo....
Durmiendo....
Señal de interrupción (2) recibida.

La función raise()

Puedes generar señales mediante la función raise(), que toma un número de señal entero como argumento y tiene la siguiente sintaxis:

int raise(int sig);

Aquí, sig es el número de señal a enviar, cualquiera de las señales: SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM, SIGHUP. A continuación, un ejemplo donde generamos una señal internamente usando la función raise():

#include <iostream>
#include <csignal>
#include <unistd.h>

using namespace std;

void signalHandler(int signum) {
    cout << "Señal de interrupción (" << signum << ") recibida.\n";
    // Limpieza y cierre de recursos aquí
    // Terminar programa
    exit(signum);
}

int main() {
    int i = 0;
    // Registrar señal SIGINT y su manejador
    signal(SIGINT, signalHandler);

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

Cuando el código anterior se compila y ejecuta, produce el siguiente resultado y sale automáticamente:

Durmiendo....
Durmiendo....
Durmiendo....
Señal de interrupción (2) recibida.

Lenguaje C

  1. Entendiendo los Tipos de Datos en C++: Fundamentos, Modificadores y Mejores Prácticas
  2. Dominando los Operadores en C++: Guía Completa con Ejemplos Prácticos
  3. Comentarios en C++: Mejores Prácticas para Código Legible y Mantenible
  4. Dominando las plantillas de clase en C++: guía práctica
  5. Manejo de archivos en C: Dominando E/S con fopen, fprintf, fread y fseek
  6. Manejo de excepciones en C++: Guía práctica con try, catch, throw
  7. Manejo de Errores en C: Mejores Prácticas y Técnicas
  8. Lenguaje de Programación C++: Visión General y Características Clave
  9. Constantes y Literales en C++: Tipos, Sintaxis y Mejores Prácticas
  10. Guía Completa de Operadores en C++: Tipos, Uso y Mejores Prácticas
  11. Dominando los Tipos Numéricos en C++: Guía Práctica