stringtranslate.com

Señal (IPC)

Las señales son mensajes estandarizados enviados a un programa en ejecución para desencadenar un comportamiento específico, como salir o manejar errores. Son una forma limitada de comunicación entre procesos (IPC), normalmente utilizada en Unix , tipo Unix y otros sistemas operativos compatibles con POSIX .

Una señal es una notificación asincrónica enviada a un proceso o a un hilo específico dentro del mismo proceso para notificarle de un evento. Los usos comunes de las señales son interrumpir, suspender, terminar o matar un proceso. Las señales se originaron en Bell Labs Unix de la década de 1970 y luego se especificaron en el estándar POSIX .

Cuando se envía una señal, el sistema operativo interrumpe el flujo normal de ejecución del proceso objetivo para entregar la señal. La ejecución se puede interrumpir durante cualquier instrucción no atómica . Si el proceso ha registrado previamente un manejador de señales , se ejecuta esa rutina. De lo contrario, se ejecuta el controlador de señales predeterminado.

Los programas integrados pueden encontrar señales útiles para las comunicaciones entre procesos, ya que las señales se destacan por su eficiencia algorítmica .

Las señales son similares a las interrupciones , la diferencia es que las interrupciones están mediadas por la CPU y manejadas por el núcleo , mientras que las señales están mediadas por el núcleo (posiblemente a través de llamadas al sistema) y manejadas por procesos individuales . [ cita necesaria ] El kernel puede pasar una interrupción como señal al proceso que la causó (los ejemplos típicos son SIGSEGV , SIGBUS , SIGILL y SIGFPE).

Historia

Enviando señales

La llamada al sistema kill (2) envía una señal específica a un proceso específico, si los permisos lo permiten. De manera similar, el comando kill(1) permite al usuario enviar señales a los procesos. La función de biblioteca rise(3) envía la señal especificada al proceso actual.

Excepciones como la división por cero , la infracción de segmentación (SIGSEGV) y la excepción de punto flotante (SIGFPE) provocarán un volcado del núcleo y finalizarán el programa.

El kernel puede generar señales para notificar procesos de eventos. Por ejemplo, SIGPIPE se generará cuando un proceso escriba en una tubería que ha sido cerrada por el lector; De forma predeterminada, esto hace que el proceso finalice, lo cual es conveniente al construir canalizaciones de shell .

Al escribir ciertas combinaciones de teclas en el terminal de control de un proceso en ejecución, el sistema le envía ciertas señales: [3]

Estas combinaciones de teclas predeterminadas con los sistemas operativos modernos se pueden cambiar con el comando stty .

Manejo de señales

Los manejadores de señales se pueden instalar con la llamada al sistema signal(2) o sigaction(2) . Si no hay un controlador de señal instalado para una señal en particular, se utiliza el controlador predeterminado. De lo contrario, la señal se intercepta y se invoca el manejador de señales. El proceso también puede especificar dos comportamientos predeterminados, sin crear un controlador: ignorar la señal (SIG_IGN) y usar el controlador de señal predeterminado (SIG_DFL). Hay dos señales que no se pueden interceptar ni manejar: SIGKILL y SIGSTOP .

Riesgos

El manejo de la señal es vulnerable a las condiciones de carrera . Como las señales son asíncronas, se puede entregar otra señal (incluso del mismo tipo) al proceso durante la ejecución de la rutina de manejo de señales.

La llamada sigprocmask(2) se puede utilizar para bloquear y desbloquear la entrega de señales. Las señales bloqueadas no se entregan al proceso hasta que se desbloquean. Las señales que no se pueden ignorar (SIGKILL y SIGSTOP) no se pueden bloquear.

Las señales pueden provocar la interrupción de una llamada al sistema en curso, dejando que la aplicación gestione un reinicio no transparente .

Los manejadores de señales deben escribirse de manera que no produzcan efectos secundarios no deseados, por ejemplo, alteración de error , alteración de la máscara de señal, cambio de disposición de la señal y otros cambios de atributos de procesos globales . El uso de funciones no reentrantes , por ejemplo, malloc o printf , dentro de los manejadores de señales, tampoco es seguro. En particular, la especificación POSIX y la señal de la página de manual de Linux (7) requieren que todas las funciones del sistema llamadas directa o indirectamente desde una función de señal sean seguras para señales asíncronas . [6] [7] La ​​página del comando man signal-safety(7) proporciona una lista de dichas funciones del sistema seguras con señales asíncronas (prácticamente el sistema llama a ); de lo contrario, es un comportamiento indefinido . [8] Se sugiere simplemente configurar alguna variable en un manejador de señales y probarla en otro lugar. [9]volatile sig_atomic_t

En cambio, los manejadores de señales pueden poner la señal en una cola y regresar inmediatamente. El hilo principal continuará "ininterrumpidamente" hasta que se tomen señales de la cola, como en un bucle de eventos . "Ininterrumpido" aquí significa que las operaciones que se bloquean pueden regresar prematuramente y deben reanudarse , como se mencionó anteriormente. Las señales deben procesarse desde la cola en el subproceso principal y no mediante grupos de trabajadores , ya que eso reintroduce el problema de la asincronicidad. Sin embargo, administrar una cola no es posible de una manera segura con señales asíncronas solo con sig_atomic_t , ya que solo se garantiza que las lecturas y escrituras individuales de dichas variables sean atómicas, no incrementos o (buscar y) decrementos, como sería necesario para una fila. Por lo tanto, efectivamente, solo se puede poner en cola de forma segura una señal por controlador con sig_atomic_t hasta que se haya procesado.

Relación con excepciones de hardware

La ejecución de un proceso puede resultar en la generación de una excepción de hardware , por ejemplo, si el proceso intenta dividir por cero o incurre en un error de página .

En sistemas operativos tipo Unix , este evento cambia automáticamente el contexto del procesador para comenzar a ejecutar un controlador de excepciones del kernel . En caso de algunas excepciones, como un error de página , el kernel tiene información suficiente para manejar completamente el evento y reanudar la ejecución del proceso.

Sin embargo, el kernel no puede procesar otras excepciones de manera inteligente y, en cambio, debe diferir la operación de manejo de excepciones al proceso defectuoso. Este aplazamiento se logra mediante el mecanismo de señales, en el que el núcleo envía al proceso una señal correspondiente a la excepción actual. Por ejemplo, si un proceso intenta dividir un número entero por cero en una CPU x86 , se generará una excepción de error de división y provocará que el núcleo envíe la señal SIGFPE al proceso.

De manera similar, si el proceso intentara acceder a una dirección de memoria fuera de su espacio de direcciones virtuales , el núcleo notificaría al proceso de esta violación a través de un SIGSEGV ( señal de violación de segmentación ). La asignación exacta entre los nombres de las señales y las excepciones depende obviamente de la CPU, ya que los tipos de excepciones difieren entre las arquitecturas.

señales POSIX

La siguiente lista documenta las señales especificadas en la Especificación única de Unix . Todas las señales se definen como macroconstantes en el <signal.h>archivo de encabezado. El nombre de la macro constante consta de un prefijo "SIG" seguido de un nombre nemotécnico para la señal.

SIGABRT ySIGIOT
"Cancelación de señal", "trampa de entrada/salida de señal"
La señal SIGABRT se envía a un proceso para decirle que aborte , es decir, que termine. La señal generalmente la inicia el proceso mismo cuando llama a abort()la función de la biblioteca estándar de C , pero puede enviarse al proceso desde afuera como cualquier otra señal.
SIGIOT indica que la CPU ha ejecutado una instrucción "trampa" explícita (sin una función definida) o una instrucción no implementada (cuando la emulación no está disponible).
Nota: "trampa de entrada/salida" es un nombre inapropiado para cualquier instrucción de "trampa" de la CPU. El término refleja el uso temprano de dichas instrucciones, predominantemente para implementar funciones de E/S, pero no están inherentemente vinculadas a la E/S del dispositivo y pueden usarse para otros fines, como la comunicación entre hosts virtuales y reales.
SIGIOT y SIGABRT suelen ser la misma señal y la recepción de esa señal puede indicar cualquiera de las condiciones anteriores.
SIGALRM ,SIGVTALRM ySIGPROF
"Alarma de señal", "alarma de temporizador virtual de señal", "alarma de temporizador de perfilado de señal"
Las señales SIGALRM, SIGVTALRM y SIGPROF se envían a un proceso cuando se alcanza el límite de tiempo correspondiente. El proceso establece estos límites de tiempo llamando alarmo setitimer. El límite de tiempo para SIGALRM se basa en tiempo real o reloj; SIGVTALRM se basa en el tiempo de CPU utilizado por el proceso; y SIGPROF se basa en el tiempo de CPU utilizado por el proceso y por el sistema en su nombre (conocido como temporizador de creación de perfiles ). En algunos sistemas, SIGALRM puede usarse internamente mediante la implementación de la sleepfunción.
SIGBUS
"Autobús de señales"
La señal SIGBUS se envía a un proceso cuando éste provoca un error de bus . Las condiciones que llevan al envío de la señal son, por ejemplo, una alineación incorrecta del acceso a la memoria o una dirección física inexistente.
SEÑAL
"Señal infantil"
La señal SIGCHLD se envía a un proceso cuando un proceso hijo finaliza , se detiene o se reanuda después de haber sido detenido. Un uso común de la señal es indicarle al sistema operativo que limpie los recursos utilizados por un proceso hijo después de su finalización sin una llamada explícita a la waitllamada del sistema.
SEÑAL
"La señal continúa"
La señal SIGCONT indica al sistema operativo que continúe (reinicie) un proceso previamente pausado por la señal SIGSTOP o SIGTSTP. Un uso importante de esta señal es el control de trabajos en el shell de Unix .
SIGFPE
" Error de señal de punto flotante "
La señal SIGFPE se envía a un proceso cuando se ha detectado una condición excepcional (pero no necesariamente errónea) en el hardware de aritmética de punto flotante o entero. Esto puede incluir división por cero , desbordamiento o subdesbordamiento de coma flotante, desbordamiento de enteros , una operación no válida o un cálculo inexacto. El comportamiento puede variar según el hardware.
Suspiro
"Corte de señal"
La señal SIGHUP se envía a un proceso cuando su terminal de control está cerrado. Fue diseñado originalmente para notificar el proceso de una caída de línea serie (un cuelgue ). En los sistemas modernos, esta señal normalmente significa que el pseudo terminal o terminal virtual de control se ha cerrado. [10] Muchos demonios (que no tienen terminal de control) interpretan la recepción de esta señal como una solicitud para recargar sus archivos de configuración y vaciar/reabrir sus archivos de registro en lugar de salir. [11] nohup es un comando para hacer que un comando ignore la señal.
SIGLO
"Señal ilegal"
La señal SIGILL se envía a un proceso cuando intenta ejecutar una instrucción ilegal , mal formada, desconocida o privilegiada .
FIRMA
"Interrupción de señal"
La señal SIGINT es enviada a un proceso por su terminal de control cuando un usuario desea interrumpir el proceso. Por lo general, esto se inicia presionando Ctrl+C , pero en algunos sistemas, se puede usar el carácter " eliminar " o la tecla " interrumpir ". [12]
SIGKILL
"Señal de muerte"
La señal SIGKILL se envía a un proceso para hacer que finalice inmediatamente ( kill ). A diferencia de SIGTERM y SIGINT, esta señal no se puede captar ni ignorar, y el proceso de recepción no puede realizar ninguna limpieza al recibir esta señal. Se aplican las siguientes excepciones:
  • Los procesos zombies no se pueden eliminar porque ya están muertos y esperando que sus procesos principales los cosechen.
  • Los procesos que están en estado bloqueado no morirán hasta que se despierten nuevamente.
  • El proceso de inicio es especial: no recibe señales que no quiere manejar y, por lo tanto, puede ignorar SIGKILL. [13] Una excepción a esta regla es cuando se rastrea init en Linux. [14] [15]
  • Es posible que un proceso en suspensión ininterrumpida no finalice (y libere sus recursos) incluso cuando se envía SIGKILL. Este es uno de los pocos casos en los que es posible que sea necesario reiniciar un sistema UNIX para resolver un problema de software temporal.
SIGKILL se utiliza como último recurso al finalizar procesos en la mayoría de los procedimientos de apagado del sistema si no sale voluntariamente en respuesta a SIGTERM. Para acelerar el procedimiento de apagado de la computadora, Mac OS X 10.6, también conocido como Snow Leopard , enviará SIGKILL a las aplicaciones que se hayan marcado como "limpias", lo que resultará en tiempos de apagado más rápidos y, presumiblemente, sin efectos nocivos. [16] El comando killall -9tiene un efecto similar, aunque peligroso, cuando se ejecuta, por ejemplo, en Linux; no permite que los programas guarden datos no guardados. Tiene otras opciones y, sin ninguna, utiliza la señal SIGTERM, más segura.
SIGPIPE
"Tubo de señal"
La señal SIGPIPE se envía a un proceso cuando intenta escribir en una tubería sin un proceso conectado al otro extremo.
SIGPOLL
"Encuesta de señales"
La señal SIGPOLL se envía cuando ocurre un evento en un descriptor de archivo monitoreado explícitamente. [17] Su uso eficaz conduce a realizar solicitudes de E/S asincrónicas ya que el núcleo sondeará el descriptor en lugar de la persona que llama. Proporciona una alternativa al sondeo activo .
SIGRTMIN aSIGRTMAX
"Señal mínima en tiempo real", "señal máxima en tiempo real"
Las señales SIGRTMIN a SIGRTMAX están diseñadas para usarse con fines definidos por el usuario. Son señales en tiempo real .
SIGQUITAR
"Señal abandonada"
La señal SIGQUIT es enviada a un proceso por su terminal de control cuando el usuario solicita que el proceso salga y realice un volcado de núcleo .
SIGSEGV
"Violación de segmentación de señal"
La señal SIGSEGV se envía a un proceso cuando hace una referencia de memoria virtual no válida o falla de segmentación , es decir, cuando realiza una violación de segmentación . [18]
SIGSTOP
"Señal de parada"
La señal SIGSTOP indica al sistema operativo que detenga un proceso para reanudarlo posteriormente.
SIGSYS
"Llamada al sistema de señales"
La señal SIGSYS se envía a un proceso cuando pasa un argumento incorrecto a una llamada al sistema . En la práctica, este tipo de señal rara vez se encuentra ya que las aplicaciones dependen de bibliotecas (por ejemplo, libc ) para realizar la llamada. SIGSYS puede ser recibido por aplicaciones que violen las reglas de seguridad de Linux Seccomp configuradas para restringirlas. SIGSYS también se puede utilizar para emular llamadas a sistemas externos, por ejemplo, emular llamadas a sistemas de Windows en Linux. [19]
SIGNO
"Terminación de señal"
La señal SIGTERM se envía a un proceso para solicitar su terminación . A diferencia de la señal SIGKILL, el proceso puede captarla e interpretarla o ignorarla. Esto permite que el proceso realice una terminación agradable, liberando recursos y guardando el estado si corresponde. SIGINT es casi idéntico a SIGTERM.
SIGTSTP
"Parada del terminal de señal"
La señal SIGTSTP es enviada a un proceso por su terminal de control para solicitarle que se detenga ( terminal stop ) . Normalmente lo inicia el usuario presionando + . A diferencia de SIGSTOP, el proceso puede registrar un controlador de señal para la señal o ignorarla.CtrlZ
SIGTTIN ySIGTTOU
Las señales SIGTTIN y SIGTTOU se envían a un proceso cuando intenta leer o escribir respectivamente desde el tty mientras está en segundo plano . Normalmente, estas señales son recibidas sólo por procesos bajo control de trabajo ; Los demonios no tienen terminales de control y, por lo tanto, nunca deberían recibir estas señales.
TRAMPA SEÑAL
"Trampa de señal"
La señal SIGTRAP se envía a un proceso cuando ocurre una excepción (o trampa ): una condición de la que un depurador ha solicitado ser informado, por ejemplo, cuando se ejecuta una función particular o cuando una variable particular cambia de valor.
SIGURG
"Señal urgente"
La señal SIGURG se envía a un proceso cuando un socket tiene datos urgentes o fuera de banda disponibles para leer.
SIGUSR1 ySIGUSR2
"Señal usuario 1", "señal usuario 2""
Las señales SIGUSR1 y SIGUSR2 se envían a un proceso para indicar condiciones definidas por el usuario .
SIGXCPU
"La señal excedió la CPU"
La señal SIGXCPU se envía a un proceso cuando ha utilizado la CPU durante un período que excede un cierto valor predeterminado configurable por el usuario. [20] La llegada de una señal SIGXCPU proporciona al proceso de recepción la oportunidad de guardar rápidamente cualquier resultado intermedio y salir correctamente, antes de que el sistema operativo lo finalice utilizando la señal SIGKILL.
SIGXFSZ
"Señal de exceso de tamaño de archivo"
La señal SIGXFSZ se envía a un proceso cuando hace crecer un archivo que excede el tamaño máximo permitido .
CABRESTANTE
"Cambio de ventana de señal"
La señal SIGWINCH se envía a un proceso cuando su terminal de control cambia de tamaño (un cambio de ventana ). [21]

Acción por defecto

Un proceso puede definir cómo manejar las señales POSIX entrantes . Si un proceso no define un comportamiento para una señal, entonces se está utilizando el controlador predeterminado para esa señal. La siguiente tabla enumera algunas acciones predeterminadas para sistemas UNIX compatibles con POSIX, como FreeBSD , OpenBSD y Linux .

Número portátil:
Para la mayoría de las señales, el número de señal correspondiente está definido por la implementación. Esta columna enumera los números especificados en el estándar POSIX. [22]
Acciones explicadas:
Terminar  : terminación anormal del proceso. El proceso finaliza con todas las consecuencias de _exit() excepto que el estado disponible para wait() y waitpid() indica una terminación anormal mediante la señal especificada.
Terminar (volcado de memoria)  : terminación anormal del proceso. Además, pueden ocurrir acciones de terminación anormales definidas por la implementación, como la creación de un archivo principal.
Ignorar  : ignora la señal.
Detener  : detener (o suspender) el proceso.
Continuar  – Continuar el proceso, si está detenido; de lo contrario, ignore la señal.

Señales varias

Las siguientes señales no están especificadas en la especificación POSIX . Sin embargo, a veces se utilizan en varios sistemas.

SIGEMT
La señal SIGEMT se envía a un proceso cuando ocurre una trampa en el emulador .
SIGNIFICAR
La señal SIGINFO se envía a un proceso cuando se recibe una solicitud de estado ( información ) desde el terminal de control.
SIGPWR
La señal SIGPWR se envía a un proceso cuando el sistema experimenta un corte de energía .
SIGLOST
La señal SIGLOST se envía a un proceso cuando se pierde un bloqueo de archivo .
SIGSTKFLT
La señal SIGSTKFLT se envía a un proceso cuando el coprocesador experimenta un fallo de pila (es decir, salta cuando la pila está vacía o empuja cuando está llena) . [23] Está definido por Linux, pero no se utiliza, donde una falla de pila del coprocesador x87 generará SIGFPE en su lugar. [24]
SIGUENTADO
La señal SIGUNUUSED se envía a un proceso cuando se realiza una llamada al sistema con un número de llamada al sistema no utilizado . Es sinónimo de SIGSYS en la mayoría de las arquitecturas. [23]
SIGCLD
La señal SIGCLD es sinónimo de SIGCHLD. [23]

Ver también

Referencias

  1. ^ McIlroy, Doctor en Medicina (1987). Un lector de Research Unix: extractos comentados del Manual del programador, 1971-1986 (PDF) (Informe técnico). CSTR. Laboratorios Bell. 139.
  2. ^ Gagliardi, Pietro. "Programación C en el Plan 9 de Bell Labs". doc.cat-v.org . Consultado el 22 de enero de 2022 .
  3. ^ "Señales de terminación". La biblioteca GNU C) .
  4. ^ "Señales de control de trabajo". La biblioteca GNU C.
  5. ^ "Señales varias". La biblioteca GNU C.
  6. ^ "Las especificaciones básicas de Open Group, edición 6, IEEE Std 1003.1, edición de 2004: Interfaces del sistema, capítulo 2". pubs.opengroup.org . Consultado el 20 de diciembre de 2020 .
  7. ^ "señal (7) - página del manual de Linux". man7.org . Consultado el 20 de diciembre de 2020 .
  8. ^ "signal-safety(7) - página del manual de Linux". man7.org . Consultado el 20 de diciembre de 2020 .
  9. ^ "Especificaciones básicas de Open Group, edición 6, IEEE Std 1003.1, edición de 2004: <signal.h>". pubs.opengroup.org . Consultado el 20 de diciembre de 2020 .
  10. ^ Michael Kerrisk (25 de julio de 2009). "señal(7)". Manual del programador de Linux (versión 3.22) . Los archivos del kernel de Linux . Consultado el 23 de septiembre de 2009 .
  11. ^ "perlipc(1)". Guía de referencia para programadores de Perl, versión 5.18 . perldoc.perl.org: documentación oficial del lenguaje de programación Perl . Consultado el 21 de septiembre de 2013 .
  12. ^ "Manejo adecuado de SIGINT y SIGQUIT" . Consultado el 6 de octubre de 2012 .
  13. ^ https://manpages.ubuntu.com/manpages/zesty/man2/kill.2.html sección NOTAS
  14. ^ "Proceso de inicio SIGKILL (PID 1)". Desbordamiento de pila .
  15. ^ "¿Puede la raíz eliminar el proceso de inicio?". Intercambio de pilas de Unix y Linux .
  16. ^ "Centro de desarrollo de Mac: Novedades de Mac OS X: Mac OS X v10.6". 28 de agosto de 2009 . Consultado el 18 de noviembre de 2017 .
  17. ^ "ioctl: controla un dispositivo STREAM". Especificación de llamada al sistema POSIX . El grupo abierto . Consultado el 19 de junio de 2015 .
  18. ^ "¿Qué es una" infracción de segmentación "?". soporte.microfocus.com . Consultado el 22 de noviembre de 2018 .
  19. ^ "Envío de usuarios de Syscall: documentación del kernel de Linux". kernel.org . Consultado el 11 de febrero de 2021 .
  20. ^ "getrlimit, setrlimit: controla el consumo máximo de recursos". Especificación de llamada al sistema POSIX . El grupo abierto . Consultado el 10 de septiembre de 2009 .
  21. ^ Clausecker, Robert (19 de junio de 2017). "0001151: Introduzca una nueva señal SIGWINCH y las funciones tcsetsize(), tcgetsize() para obtener/establecer el tamaño de la ventana del terminal". Rastreador de defectos del grupo Austin . Grupo Austin . Consultado el 12 de octubre de 2017 . Aceptado como marcado
  22. ^ "IEEE Std 1003.1-2017 - matar". IEEE, Grupo Abierto. La correspondencia entre los valores enteros y el valor sig utilizado se muestra en la siguiente lista. Los efectos de especificar cualquier número de señal distinto de los que se enumeran a continuación no están definidos.
  23. ^ abc "señal (7) - páginas del manual de Linux". manpages.courier-mta.org . Consultado el 22 de noviembre de 2018 .
  24. ^ "Linux 3.0 x86_64: ¿Cuándo se genera SIGSTKFLT?". Desbordamiento de pila .

enlaces externos