Señal
Una señal es un evento que se genera para notificar a un proceso o hilo que ha llegado una situación importante. Cuando un proceso o hilo ha recibido una señal, el proceso o el hilo detendrá lo que está haciendo y tomará alguna acción. La señal puede ser útil para la comunicación entre procesos.
Señales estándar
Las señales se definen en el archivo de encabezado señal.H como una macro constante. El nombre de la señal ha comenzado con un "sig" y seguido de una breve descripción de la señal. Entonces, cada señal tiene un valor numérico único. Su programa siempre debe usar el nombre de las señales, no el número de señales. La razón es que el número de señal puede diferir según el sistema, pero el significado de los nombres será estándar.
La macro Nsig ¿Está definido el número total de señal?. El valor de Nsig es uno mayor que el número total de señal definida (todos los números de señal se asignan consecutivamente).
Las siguientes son las señales estándar:
Nombre de señal | Descripción |
Suspiro | Colgando el proceso. La señal de suspiro se utiliza para informar la desconexión del terminal del usuario, posiblemente porque se pierde o cuelga una conexión remota. |
Firme | Interrumpir el proceso. Cuando el usuario escribe el personaje int (normalmente Ctrl + c) se envía la señal Sigint. |
Sigquín | Dejar el proceso. Cuando el usuario escribe el carácter de abandono (normalmente ctrl + \) se envía la señal de sigquit. |
Sigillón | Instrucción ilegal. Cuando se intenta ejecutar basura o instrucción privilegiada, se genera la señal Sigill. Además, se puede generar Sigill cuando la pila se desborda, o cuando el sistema tiene problemas para ejecutar un controlador de señal. |
Siglo | Trampa. Una instrucción de punto de interrupción y otras instrucciones de trampa generarán la señal SigTrap. El depurador usa esta señal. |
Sigabrt | Abortar. La señal sigabrt se genera cuando se llama a la función de abort (). Esta señal indica un error detectado por el programa mismo e informado por la llamada de función ABORT (). |
Sigfpe | Excepción de punto flotante. Cuando se produjo un error aritmético fatal, se genera la señal SIGFPE. |
Sigusr1 y Sigusr2 | Las señales Sigusr1 y Sigusr2 pueden usarse como desee. Es útil escribir un controlador de señal para ellos en el programa que recibe la señal para una comunicación simple entre procesos. |
Acción predeterminada de las señales
Cada señal tiene una acción predeterminada, una de las siguientes opciones:
Término: El proceso terminará.
Centro: El proceso terminará y producirá un archivo de volcado central.
IGN: El proceso ignorará la señal.
Detener: El proceso se detendrá.
Cont: El proceso continuará por ser detenido.
La acción predeterminada se puede cambiar utilizando la función del controlador. La acción predeterminada de alguna señal no se puede cambiar. Sigkill y Sigabrt La acción predeterminada de la señal no se puede cambiar ni ignorar.
Manejo de la señal
Si un proceso recibe una señal, el proceso tiene una opción de acción para ese tipo de señal. El proceso puede ignorar la señal, puede especificar una función de controlador o aceptar la acción predeterminada para ese tipo de señal.
Podemos manejar la señal usando señal o siga función. Aquí vemos cómo el más simple señal() la función se usa para manejar señales.
int señal () (int firm, void (*func) (int))El señal() llamará al concurrido función si el proceso recibe una señal signo. El señal() Devuelve un puntero a la función concurrido Si tiene éxito o devuelve un error a errno y -1 de lo contrario.
El concurrido El puntero puede tener tres valores:
Ejemplo de controlador de señal básico
#incluirEn la captura de pantalla de la salida del ejemplo1.c, podemos ver que en la función principal se está ejecutando el bucle infinito. Cuando el usuario escribió CTRL+C, se invoca la parada de ejecución de la función principal y la función del controlador de la señal. Después de completar la función del controlador, se reanudó la ejecución de la función principal. Cuando el tipo de usuario se escribe Ctrl+\, el proceso se renuncia.
Ignorar el ejemplo de señales
#incluirAquí la función del controlador está registrado en Sig_ign () función para ignorar la acción de la señal. Entonces, cuando el usuario escribió Ctrl+C, Firme La señal está generando pero la acción se ignora.
Ejemplo de controlador de señal de reinicio
#incluirEn la captura de pantalla de la salida del ejemplo3.C, podemos ver que cuando el usuario escribió Ctrl+C, se invoca la función del controlador. En la función del controlador, el controlador de señal se registra en Sig_dfl Para una acción predeterminada de la señal. Cuando el usuario escribió CTRL+C por segunda vez, el proceso finaliza, que es la acción predeterminada de Firme señal.
Envío de señales:
Un proceso también puede enviar explícitamente señales a sí misma o a otro proceso. La función Raise () y Kill () se puede usar para enviar señales. Ambas funciones se declaran en la señal.H Archivo de encabezado H.
int Raise (int Signum)La función Raise () utilizada para enviar una señal signo al proceso de llamadas (en sí). Devuelve cero si tiene éxito y un valor distinto de cero si falla.
int kill (pid_t pid, int signum)La función de matar utilizada para enviar una señal signo a un grupo de proceso o proceso especificado por pid.
Ejemplo de manejador de señal Sigusr1
#incluirAquí, el proceso se envía la señal Sigusr1 a sí misma usando la función Raise ().
Programa de ejemplo de criar con Kill
#incluirAquí, el proceso envía Sigusr1 Señalizar a sí mismo usando matar() función. getpid () se usa para obtener la identificación del proceso de sí mismo.
En el siguiente ejemplo, veremos cómo se comunican los procesos de los padres y el niño (comunicación entre procesos) utilizando matar() y función de señal.
Comunicación infantil de los padres con señales
#incluirAquí, tenedor() La función crea el proceso infantil y devuelve cero al proceso infantil y la identificación del proceso infantil al proceso principal. Entonces, PID ha sido revisado para decidir el proceso de los padres e hijos. En el proceso de los padres, se durme durante 1 segundo para que el proceso infantil pueda registrar la función del controlador de señal y esperar la señal del padre. Después de 1 segundo proceso de proceso de los padres, envíe Sigusr1 Señal al proceso del niño y espere la señal de respuesta del niño. En el proceso infantil, primero está esperando la señal de los padres y cuando se recibe la señal, se invoca la función del controlador. Desde la función del controlador, el proceso infantil envía otro Sigusr1 Señal al padre. Aquí getppid () La función se utiliza para obtener la identificación del proceso de los padres.
Conclusión
La señal en Linux es un gran tema. En este artículo, hemos visto cómo manejar la señal desde lo básico, y también obtener el conocimiento de cómo generar la señal, cómo un proceso puede enviar señal a sí misma y otro proceso, cómo se puede utilizar la señal para la comunicación entre procesos.