LINUX

Manejo de señales en Linux a través de la función signal().

En la parte 1 de esta serie sobre señales de Linux, discutimos los fundamentos de las señales en Linux. En este artículo, discutiremos los aspectos prácticos del manejo de señales en Linux a través de señal() función. Todas las explicaciones irán acompañadas de ejemplos prácticos.

función de señal c

Manejadores de señales

Un manejador de señales es una función especial (definida en el código del programa de software y registrada en el núcleo) que se ejecuta cuando llega una determinada señal. Esto hace que se cancele el proceso de ejecución actual y también se guardan todos los registros actuales. El proceso suspendido se reanuda una vez que regresa el controlador de señales.

La función señal().

La forma más fácil de registrar la función de manejo de señales con el kernel es usando señal() función.

Aquí está su sintaxis señal() función:

#include <signal.h>

typedef void (*sighandler_t)(int);

sighandler_t signal(int signum, sighandler_t handler);

Entonces puede ver que un controlador de señal es una función que acepta un argumento entero pero devuelve vacío. El manejador de señales se puede registrar con el kernel usando señal() función (descrita anteriormente) que acepta un número de señal específico y un nombre de función de manejo de señal (aunque puede haber otros valores para el segundo argumento, pero los discutiremos más adelante).

Aquí hay un ejemplo práctico de manejo de señales en Linux a través de señal() función:

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

void sig_handler(int sig_num)
{
if(sig_num == SIGINT)
{
printf("n Caught the SIGINT signaln");
}
else
{
printf("n Caught the signal number [%d]n", sig_num);
}

// Do all the necessary clean-up work here

exit(sig_num);
}

int main(void)
{
//Register signal handler through the signal() function
signal(SIGINT, sig_handler);

while(1)
{
//simulate a delay -- as if the program is doing some other stuff
sleep(1);
}

return 0;
}

En el código del programa que se muestra arriba:

  • Dentro de la función main(), la función signal() se usa para registrar un controlador (sig_handler()) para SEGUIR señal.
  • El bucle while simula un retraso infinito. Así que el programa está esperando. SEÑAL señal hasta el infinito.
  • El controlador de señal «sig_handler» imprime una declaración de depuración que verifica si la señal deseada es SEGUIR O no.
  • El manejador de señales se usa principalmente para hacer toda la limpieza y las cosas relacionadas después de que se entrega una señal a un proceso.

Aquí está la salida de este programa:

$ ./sig_example
^C
Caught the SIGINT signal

Entonces puede ver que el programa (sig_example) se ejecutó y luego la señal SEGUIR se transmite presionando la combinación de teclas Ctrl+c. Como se puede ver en la salida de depuración, el controlador de señal se ejecutó tan pronto como la señal SEGUIR fue entregado al proceso.

Disposición de una señal

Para entender el concepto de disposición de una señal, repasemos la declaración de la función señal:

sighandler_t signal(int signum, sighandler_t handler);

El segundo argumento de la función signal() se conoce como la disposición de una señal. Hasta ahora, hemos aprendido que el segundo argumento es una función de manejo de señales, pero este no es el único tipo de método de disposición de señales. Otras formas de disponer de la señal aa son especificar SIG_IGN o SIG_DFL como el segundo argumento de la función de señal.

Si la disposición se establece en SIG_IGN luego la señal (pasada como el primer argumento a señal() función) se ignora y no se entrega al proceso, pero si la disposición se establece en SIG_DFL luego se toma la acción por defecto correspondiente a esa señal.

Aquí hay un código de ejemplo que ignora SEGUIR señal:

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

int main(void)
{
//Register signal handler through the signal() function
signal(SIGINT, SIG_IGN);

while(1)
{
//simulate a delay -- as if the program is doing some other stuff
sleep(1);
}

return 0;
}

Entonces puede ver que ahora no hay una función de controlador de señal porque el segundo argumento de la función de señal se reemplaza por SIG_IGN.

Aquí está la salida de este programa:

$ ./sig_example
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C

Entonces puedes ver esto a pesar de presionar repetidamente Ctrl+c, el proceso no se vio afectado de ninguna manera. Esto se debe a que la señal SEGUIR (generado cuando Ctrl+c se presiona) se ignora.

De manera similar, aquí hay un código de programa que deja SEGUIR a su acción por defecto:

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

int main(void)
{
//Register signal handler through the signal() function
signal(SIGINT, SIG_DFL);

while(1)
{
//simulate a delay -- as if the program is doing some other stuff
sleep(1);
}

return 0;
}

Entonces puede ver que el segundo argumento de la función de señal (en el código que se muestra arriba) se reemplaza por SIG_DFL en este caso.

Y aquí está el resultado de este programa:

$ ./sig_example
^C
$

Entonces puedes ver que presionando Ctrl+c finalizó el proceso porque la acción predeterminada a SEGUIR es terminar el proceso.

Limitaciones de la función signal().

A pesar de que señal() es la forma más antigua y fácil de manejar señales, tiene algunas limitaciones importantes:

  • La función signal() no bloquea otras señales mientras el manejador de señales se ejecuta para la señal actual. Esto puede producir resultados no deseados.
  • La acción de la señal para una señal en particular se restablece a su valor predeterminado, es decir, SIG_DFL tan pronto como se entregue la señal. Esto significa que incluso si el manejador de la señal vuelve a establecer la acción de la señal como primer paso, existe una ventana de tiempo posible en la que la señal puede ocurrir nuevamente mientras su acción se establece en SIG_DFL.

Debido a estas importantes limitaciones, ahora se recomienda utilizar la función seguiracción() que supera todas estas limitaciones.

Publicaciones relacionadas

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Botón volver arriba
Cerrar