¿Qué es la programación
de señales?
“Programación de señales” es un término que se usa a menudo para referirse
a un programa de computadora que funciona principalmente en respuesta a
señales o eventos generados por algún cambio de estado o por entrada del
usuario. Casi cualquier parte de un sistema informático, desde un dispositivo
periférico hasta el propio sistema operativo, puede generar una señal que
puede ser capturada por una aplicación y luego procesada. En muchas formas,
la programación de señales se asemeja a la programación impulsada por
eventos. Algunos de los usos más comunes para la programación de señales
son las interfaces gráficas de usuario que responden a la entrada del usuario,
las comunicaciones de red y los programas de bajo nivel que capturan y
manejan señales específicas del sistema.
Una señal en programación informática puede definirse como un mensaje, un
evento o una interrupción, según su origen, la arquitectura del sistema o incluso
la preferencia del programador. En términos más amplios, es un indicador de
que algún estado o dato ha cambiado y, en ocasiones, va acompañado de
información adicional sobre el cambio que se ha producido. La señal puede ser
generada por el usuario cuando se presiona una tecla, desde hardware como
un monitor cuando ocurre un retroceso vertical, o incluso desde el sistema
operativo cuando ocurre algo como una falla de página durante la asignación
de memoria.
Dentro de una aplicación, la programación de señales puede adoptar varios
tipos de arquitecturas, pero una de las más comunes es un modelo de escucha
u observador. En este método, un fragmento de código definido por el usuario
se puede pasar de alguna manera a un manejador de señales, generalmente
dentro del sistema operativo, que luego llama a ese fragmento de código para
procesar cualquier señal que coincida con lo que busca la función. El tipo de
señal que una función puede manejar a menudo está determinado por una
variable conocida como máscara de señal, por lo que algunas señales no se
pasan a rutinas que no están diseñadas para manejarlas.
Un segundo tipo de programación de señales implica tener un programa que
implemente una cola que acepte señales entrantes. Esta cola se sondea en el
ciclo de ejecución principal del programa y el programa reacciona una vez que
una señal entra en la cola. Luego, cada señal se puede clasificar, manejar,
ignorar o pasar de manera lógica a otro proceso.
Pueden surgir algunas dificultades en la programación de señales cuando se
utilizan procesos concurrentes o aplicaciones multiproceso. Las complicaciones
pueden surgir si, por ejemplo, dos subprocesos separados están escuchando
señales generadas por dos dispositivos de entrada de usuario separados o
desde dos enchufes de red. Si dos usuarios intentan simultáneamente realizar
un cambio en algunos datos, los datos del programa podrían perder la
sincronización y aparecer de manera diferente para cada usuario. El uso de
una cola lineal o la implementación de métodos de sincronización de
subprocesos pueden ayudar a prevenir esta situación.
Señal (informática)
Una señal (del inglés signal) es una forma limitada de comunicación entre
procesos empleada en Unix y otros sistemas operativos compatibles con
POSIX. En esencia es una notificación asíncrona enviada a un proceso para
informarle de un evento. Cuando se le manda una señal a un proceso, el
sistema operativo modifica su ejecución normal. Si se había establecido
anteriormente un procedimiento (handler) para tratar esa señal se ejecuta este,
si no se estableció nada previamente se ejecuta la acción por defecto para esa
señal.
Envío de señales
Al escribir Ctrl-C en el shell donde se ejecuta un proceso el sistema le envía
una señal SIGINT, que por defecto causa la terminación del proceso. Ctrl-Z
hace que el sistema envíe una señal SIGTSTP que suspende la ejecución del
proceso.
La llamada al sistema kill enviará la señal especificada al proceso.
Excepciones como la división por cero o la violación de segmento generan
señales.
Los procesos pueden enviar señales tanto a otros procesos como a sí mismos
usando kill(2) (por supuesto con los permisos necesarios) por ejemplo
kill(pid,SIGUSR1) siendo pid el identificador del proceso al cual deseamos
enviar la señal SIGUSR1.
El núcleo puede generar una señal para informar de un evento a un proceso.
Por ejemplo, SIGPIPE se genera cuando un proceso escribe en una tubería
que había sido cerrada por el proceso que leía de ella.
Manipulación de señales
Los manipuladores de señales se establecen mediante la llamada al sistema
signal(). Si hay un manipulador de señal para una señal dada se invoca y, si no
lo hay, se usa el manipulador por defecto. El proceso puede especificar
también dos comportamientos por defecto sin necesidad de crear un
manipulador: ignorar la señal (SIG_IGN) y usar el manipulador por defecto
(SIG_DFL). Hay dos señales que no pueden ser interceptadas ni manipuladas:
SIGKILL y SIGSTOP.
La manipulación de señales es vulnerable a que se produzca una condición de
carrera, pues las señales son asíncronas y puede ocurrir que llegue otra señal
(incluso del mismo tipo) al proceso mientras transcurre la ejecución de la
función que manipula la señal. Puede usarse la función sigprocmask para
desbloquear la entrega de señales.
Las señales pueden interrumpir una llamada al sistema en proceso, dejando en
manos de la aplicación la gestión del PCLSRing.