[Sistema operativo Linux] Realización de la captura de señales en la programación del sistema Linux

En la programación de sistemas Linux, las señales son un mecanismo importante para la comunicación y el control entre procesos. Cuando ocurre un evento determinado, como que el usuario presione las teclas Ctrl+C, el sistema operativo envía una señal al proceso, que el proceso puede captar y manejar en consecuencia. Este blog presentará la clasificación, captura y procesamiento de señales, así como el funcionamiento predeterminado de las señales. Espero que a través de este blog puedan comprender mejor el concepto y la aplicación de señales en la programación del sistema Linux.
inserte la descripción de la imagen aquí


1. ¿Qué es una señal?

En los sistemas Linux, las señales son un mecanismo para la comunicación y el control entre procesos. Cuando ocurre un evento, el kernel envía una señal al proceso, y el proceso puede elegir capturar y procesar la señal, o utilizar el método de procesamiento predeterminado.

Las señales pueden ser activadas por varios eventos, como que el usuario presione Ctrl+Cuna tecla, un error en el proceso o la salida de un proceso hijo. Cada señal tiene un número único y un comportamiento predeterminado predefinido.


2. Clasificación de señales

  1. Señales Estándar : Estas señales están numeradas entre 1 y 31 y están definidas en el estándar POSIX. Por ejemplo, la señal SIGINT (número 2) se activa cuando el usuario presiona la tecla Ctrl+C, y la señal SIGTERM (número 15) es la señal utilizada para finalizar el proceso.

  2. Señales en tiempo real : Estas señales están numeradas entre 32 y 63 y también están definidas en el estándar POSIX. Las señales en tiempo real proporcionan mayor prioridad y una sincronización de disparo más precisa.

  3. Señales definidas por el usuario : estas señales pueden ser definidas por los usuarios y sus números son mayores que 64.


3. Método de procesamiento de señales

  1. Ignorar (Ignorar) : El proceso puede optar por ignorar una señal específica, de modo que cuando ocurra la señal, el proceso no hará nada. Sin embargo, algunas señales no se pueden ignorar, como SIGKILL y SIGSTOP.

  2. Captura : un proceso puede captar una señal registrando un controlador de señales. Cuando ocurre una señal, el kernel llamará a la función de manejo de señales registrada para manejar la señal.

  3. Realizar acción predeterminada (Acción predeterminada) : cada señal tiene un comportamiento predeterminado predefinido, como finalizar el proceso, finalizar el proceso y generar un archivo de volcado de núcleo, etc.


4. Captura y procesamiento de señales.

4.1signal

Rol : signalLa función se utiliza para capturar y procesar señales.

Prototipo :

#include <signal.h>

void (*signal(int signum, void (*handler)(int)))(int);

Parámetros :

  • signum: El número de señal a capturar.
  • handler: Puntero a la función del controlador de señales.

Valor de retorno : Devuelve el puntero a la función de procesamiento anterior de la señal. Devuelve si ocurre un error SIG_ERR.

Ejemplo : a continuación se muestra un ejemplo que demuestra cómo usar signaluna función para capturar y manejar la señal SIGINT (el usuario presiona las teclas Ctrl+C).

#include <stdio.h>
#include <signal.h>

void sigint_handler(int signum) {
    
    
    printf("Received SIGINT signal\n");
}

int main() {
    
    
    // 注册SIGINT信号的处理函数
    signal(SIGINT, sigint_handler);

    printf("Press Ctrl+C to send SIGINT signal\n");

    while (1) {
    
    
        // 无限循环,等待信号的发生
    }

    return 0;
}

Explicación de ejemplo :

  • En el ejemplo anterior, definimos una sigint_handlerfunción de manejo de señales llamada. Cuando se recibe una señal SIGINT, se llama a esta función y se imprime un mensaje.
  • En mainla función, usamos signalla función para registrar sigint_handlerla función como controlador de la señal SIGINT. De esta manera, cuando el usuario presiona la tecla Ctrl+C, el sistema operativo enviará una señal SIGINT al proceso y llamará a sigint_handleruna función para manejar la señal.
  • En mainel bucle infinito de la función, esperamos a que se produzca la señal. De esta manera, el proceso se ejecuta hasta que recibe una señal SIGINT u otra señal de terminación.
  • Cuando presionamos la tecla Ctrl+C, se activará la señal SIGINT, el proceso llamará sigint_handlera la función e imprimirá un mensaje.

4.2sigaction

Rol : sigactionLa función es otra forma de capturar y procesar señales, signalque proporciona más flexibilidad y confiabilidad que la función.

Prototipo :

#include <signal.h>

int sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);

Parámetros :

  • signum: El número de señal a capturar.
  • act: struct sigactionpuntero a una estructura que especifica el nuevo método de manejo de señales.
  • oldact: Un struct sigactionpuntero a una estructura utilizada para guardar el método de procesamiento de señal anterior.

Valor de retorno : si tiene éxito, devuelve 0; en caso de error, devuelve -1.

Ejemplo : a continuación se muestra un ejemplo que demuestra cómo usar sigactionuna función para capturar y manejar la señal SIGINT (el usuario presiona las teclas Ctrl+C).

#include <stdio.h>
#include <signal.h>

void sigint_handler(int signum) {
    
    
    printf("Received SIGINT signal\n");
}

int main() {
    
    
    struct sigaction sa;
    sa.sa_handler = sigint_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;

    // 注册SIGINT信号的处理函数
    sigaction(SIGINT, &sa, NULL);

    printf("Press Ctrl+C to send SIGINT signal\n");

    while (1) {
    
    
        // 无限循环,等待信号的发生
    }

    return 0;
}

Explicación de ejemplo :

  • En el ejemplo anterior, definimos una sigint_handlerfunción de manejo de señales llamada. Cuando se recibe una señal SIGINT, se llama a esta función y se imprime un mensaje.
  • Creamos una struct sigactionestructura say sigint_handlerespecificamos la función como controlador de señal.
  • sigemptysetInicializado con una función sa.sa_mask, lo que significa que no es necesario bloquear otras señales al procesar la señal SIGINT.
  • sa.sa_flagsEstablezca en 0 para indicar que no se requieren indicadores especiales.
  • Utilice sigactionuna función para saregistrar una estructura sobre cómo manejar la señal SIGINT.
  • En mainel bucle infinito de la función, esperamos a que se produzca la señal. De esta manera, el proceso se ejecuta hasta que recibe una señal SIGINT u otra señal de terminación.
  • Cuando presionamos la tecla Ctrl+C, se activará la señal SIGINT, el proceso llamará sigint_handlera la función e imprimirá un mensaje.

5. Acciones predeterminadas para señales

Si no se capta una señal o el controlador de señales captadas regresa, el proceso realizará la acción predeterminada para la señal.

Por ejemplo, un proceso finaliza de forma predeterminada cuando se recibe una señal SIGTERM. A continuación se muestra un ejemplo que demuestra el funcionamiento predeterminado de la señal SIGTERM:

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

void sigterm_handler(int signum) {
    
    
    printf("Received SIGTERM signal\n");
}

int main() {
    
    
    // 注册SIGTERM信号的处理函数
    signal(SIGTERM, sigterm_handler);

    printf("Press Ctrl+C to send SIGTERM signal\n");

    while (1) {
    
    
        // 无限循环,等待信号的发生
    }

    return 0;
}

En el ejemplo anterior, captamos la señal SIGTERM y registramos sigterm_handlerla función como controlador. Cuando se recibe una señal SIGTERM, se llama a esta función y se imprime un mensaje.


Resumir

Las señales son un mecanismo para la comunicación y el control entre procesos en los sistemas Linux. Podemos manejar la señal capturándola y registrando una función de controlador. Al manejar una señal, podemos optar por ignorarla, captarla o realizar una acción predeterminada.

Supongo que te gusta

Origin blog.csdn.net/Goforyouqp/article/details/132361279
Recomendado
Clasificación