Búsqueda de sitios web

Explicación de la generación y el manejo de señales de Linux


Las señales son una parte integral de los sistemas operativos, incluido Linux. Estos son los conceptos básicos de generación y manejo de señales en el kernel de Linux.

El mecanismo de señalización en el kernel de Linux permite que las aplicaciones en ejecución notifiquen al sistema de manera asíncrona cuando ocurre un nuevo evento. Debido a su naturaleza, este mecanismo de señalización se conoce generalmente como interrupciones de software. Al igual que las interrupciones de hardware, las señales interrumpen el flujo normal de una aplicación y es impredecible cuándo una aplicación recibirá una señal.

Profundicemos en el mecanismo de señalización en Linux y comprendamos lo que sucede detrás de escena.

Conceptos básicos de señales en Linux

En Linux, los procesos generan señales en tres situaciones básicas:

  • Cuando se presenta una situación excepcional en el lado del hardware. Por ejemplo, puede pensar en eventos como que la aplicación intente acceder a una región fuera del espacio de direcciones permitido (falla de segmentación) o genere un código de máquina que incluya una operación de división por cero.

  • Situaciones como el uso de combinaciones de teclas como Ctrl + C o Ctrl + Z en la consola por parte del usuario, cambiar el tamaño de la pantalla de la consola o enviar una señal de eliminación.

  • El temporizador establecido en la aplicación expira, el límite de CPU asignado a la aplicación es alto, los datos llegan a un descriptor de archivo abierto, etc.

El concepto de señales ha existido desde las primeras versiones de Unix. Previamente, había varias diferencias entre las versiones de Unix con respecto al procesamiento de señales. Más tarde, con la estandarización POSIX realizada para la gestión de señales, Linux y otros derivados de Unix comenzaron a seguir estos estándares. Por esta razón, los conceptos de señales Unix y señales POSIX, que puede encontrar en algunos documentos, señalan las diferencias.

Números de señal

Las señales tienen varios valores numéricos, comenzando con uno. Por ejemplo, la señal 1 es una señal HUP en casi todos los sistemas, o la señal 9 es una señal KILL.

Sin embargo, se desaconseja encarecidamente el uso de estos números cuando utilice señales en sus aplicaciones. Para señales POSIX, el archivo signal.h debe estar en la aplicación y el desarrollador debe usar las definiciones constantes de números relacionados como SIGHUP, SIGKILL , etc. en su lugar.

Si examina el archivo /usr/include/signal.h en su sistema, puede ver las operaciones adicionales y otros archivos incluidos mirando las definiciones de valores como __USE_POSIX , __USE_XOPEN, __USE_POSIX199309, etc. en el archivo. Puede encontrar los números de señal disponibles en los sistemas Linux en el archivo /usr/include/asm-generic/signal.h, que no necesita incluir directamente en el código de su aplicación.

Generación y envío de señales

La generación de señal se produce debido a un evento. Sin embargo, el envío (entrega) de la señal a la aplicación relevante no ocurre simultáneamente con la generación de la señal.

Para que la señal se envíe a la aplicación, la aplicación debe estar ejecutándose actualmente y tener recursos de CPU. Por lo tanto, el envío de una señal a una aplicación específica ocurre cuando la aplicación correspondiente vuelve a funcionar después del cambio de contexto.

El concepto de señal pendiente

Durante el tiempo que transcurre desde la generación hasta la transmisión de la señal, las señales están en estado de espera. Puede acceder a la cantidad de señales pendientes y la cantidad de señales pendientes permitidas para un proceso desde el archivo /proc/PID/status.

# For a process with PID: 2299
cat /proc/2299/status 

# Output
...
SigQ: 2/31630
...

Máscaras de señal y bloqueo

La hora exacta en que llegarán las señales a menudo es impredecible para la aplicación. Por lo tanto, pueden ocurrir algunas interrupciones críticas durante cualquier operación. Esto puede causar problemas importantes para una aplicación a gran escala.

Para evitar algunas situaciones indeseables como esta, es necesario utilizar máscaras de señal. Así es posible bloquear algunas señales antes de una operación crítica. En esta etapa, es importante completar la parte crítica y eliminar los bloques definidos. Este proceso es algo a lo que el desarrollador de aplicaciones debe prestar atención.

Cuando la aplicación bloquea una señal, otras señales del mismo tipo generadas estarán en estado de espera hasta que se desbloqueen. En la aplicación, también se proporciona el envío de señales pendientes tan pronto como se elimina el bloqueo.

De esta manera, los mismos tipos de señales puestas en espera en el momento del bloqueo se envían a la aplicación solo una vez después de que se elimine el bloqueo en uso normal. La situación es diferente para las señales en tiempo real.

Tipos de señales de Linux

Las acciones predeterminadas pueden variar según los tipos de señal. Si la aplicación que recibe la señal correspondiente no tiene una función de manejo de señales, se lleva a cabo la acción predeterminada. A veces, esto significa terminar la aplicación y, a veces, ignorar la señal.

Algunas señales no se pueden capturar en la capa de aplicación, estas señales siempre realizan la acción predeterminada (como la señal KILL).

Además de algunas acciones que provocan la finalización de una aplicación, también se genera un archivo de volcado del núcleo. Los archivos de volcado del núcleo, creados al escribir la tabla de memoria virtual del proceso relacionado en el disco, ayudan al usuario a examinar la información de estado antes de que finalice el proceso con herramientas de depuración en las siguientes etapas.

Los siguientes valores se basan en una arquitectura MIPS ejemplar:

Signal

Number

Default Action

Can It Be Caught?

SIGHUP

1

Terminate application

Yes

SIGINT

2

Terminate application

Yes

SIGQUIT

3

Terminate application (core dump)

Yes

SIGILL

4

Terminate application (core dump)

Yes

SIGTRAP

5

Terminate application (core dump)

Yes

SIGABRT

6

Terminate application (core dump)

Yes

SIGFPE

8

Terminate application (core dump)

Yes

SIGKILL

9

Terminate application

No

SIGBUS

10

Terminate application (core dump)

Yes

SIGSEGV

11

Terminate application (core dump)

Yes

SIGSYS

12

Terminate application (core dump)

Yes

SIGPIPE

13

Terminate application

Yes

SIGALRM

14

Terminate application

Yes

SIGTERM

15

Terminate application

Yes

SIGUSR1

16

Terminate application

Yes

SIGUSR2

17

Terminate application

Yes

SIGCHLD

18

Ignore

Yes

SIGTSTP

20

Stop

Yes

SIGURG

21

Ignore

Yes

SIGPOLL

22

Terminate application

Yes

SIGSTOP

23

Stop

No

SIGCONT

25

Continue if stopped

Yes

SIGTTIN

26

Stop

Yes

SIGTTOU

27

Stop

Yes

SIGVTALRM

28

Terminate application

Yes

SIGPROF

29

Terminate application

Yes

SIGXCPU

30

Terminate application (core dump)

Yes

SIGXFSZ

31

Terminate application (core dump)

Yes

Ciclo de vida de las señales en Linux

Las señales pasan por tres etapas. Se producen principalmente en la fase de producción, por el núcleo o cualquier proceso, y se representan con un número. Trabajan con ligereza y rapidez, ya que no tienen ninguna carga extra sobre ellos. Pero si observa el lado POSIX, verá que las señales en tiempo real pueden transmitir datos adicionales.

La fase de entrega de las señales viene después de la fase de producción. Normalmente, las señales llegan a la aplicación desde el kernel lo más rápido posible. Sin embargo, a veces las aplicaciones pueden bloquear señales mientras realizan operaciones críticas. En tales casos, la señal permanece pendiente hasta que se realiza la transacción.

Al igual que las señales, los procesos también son una parte integral del ecosistema Linux. Comprender qué son los procesos y cómo funcionan es crucial si planea convertirse en administrador del sistema Linux.

Artículos relacionados: