Saltar al contenido

¿Cuál es la diferencia entre sigaction y señal?

Luego de mucho luchar pudimos encontrar la respuesta de este inconveniente que algunos de nuestros lectores de este sitio web tienen. Si tienes algún detalle que aportar no dejes de dejar tu conocimiento.

Solución:

Utilizar sigaction() a menos que tenga razones muy convincentes para no hacerlo.

los signal() La interfaz tiene la antigüedad (y por lo tanto la disponibilidad) a su favor, y está definida en el estándar C. Sin embargo, tiene una serie de características indeseables que sigaction() evita, a menos que use las banderas agregadas explícitamente a sigaction() para permitirle simular fielmente el antiguo signal() conducta.

  1. los signal() la función no bloquea (necesariamente) la llegada de otras señales mientras se ejecuta el controlador actual; sigaction() puede bloquear otras señales hasta que regrese el controlador actual.
  2. los signal() La función (generalmente) restablece la acción de la señal de nuevo a SIG_DFL (predeterminado) para casi todas las señales. Esto significa que el signal() handler debe reinstalarse como su primera acción. También abre una ventana de vulnerabilidad entre el momento en que se detecta la señal y se reinstala el controlador, durante el cual, si llega una segunda instancia de la señal, se produce el comportamiento predeterminado (generalmente termina, a veces con perjuicio, también conocido como volcado del núcleo).
  3. El comportamiento exacto de signal() varía entre los sistemas, y los estándares permiten esas variaciones.

Estas son generalmente buenas razones para usar sigaction() en lugar de signal(). Sin embargo, la interfaz de sigaction() es innegablemente más complicado.

Cualquiera de los dos que use, no se deje tentar por las interfaces de señal alternativas como
sighold(),
sigignore(),
sigpause() y
sigrelse(). Son nominalmente alternativas a sigaction(), pero apenas están estandarizados y están presentes en POSIX por compatibilidad con versiones anteriores en lugar de para un uso serio. Tenga en cuenta que el estándar POSIX dice que su comportamiento en programas de subprocesos múltiples no está definido.

Los programas y señales de subprocesos múltiples son otra historia complicada. AFAIK, ambos signal() y sigaction() están bien en aplicaciones de subprocesos múltiples.

Cornstalks observa:

La página del manual de Linux para signal() dice:

  Los efectos de signal() en un proceso de subprocesos múltiples no están especificados.

Por lo tanto, creo sigaction() es el único que se puede utilizar de forma segura en un proceso de subprocesos múltiples.

Eso es interesante. La página del manual de Linux es más restrictiva que POSIX en este caso. POSIX especifica para signal():

Si el proceso es de subprocesos múltiples, o si el proceso es de un solo subproceso y se ejecuta un controlador de señal que no sea como resultado de:

  • El proceso llamando abort(), raise(), kill(), pthread_kill()o sigqueue() para generar una señal que no esté bloqueada
  • Una señal pendiente que se desbloquea y se entrega antes de que regrese la llamada que la desbloqueó

el comportamiento no está definido si el controlador de señal se refiere a cualquier objeto que no sea errno con static duración del almacenamiento que no sea asignando un valor a un objeto declarado como volatile sig_atomic_to si el manejador de señales llama a cualquier función definida en este estándar que no sea una de las funciones enumeradas en Conceptos de señales.

Entonces POSIX especifica claramente el comportamiento de signal() en una aplicación de subprocesos múltiples.

Sin embargo, sigaction() es preferible en prácticamente todas las circunstancias, y el código portátil de subprocesos múltiples debe usar sigaction() a menos que haya una razón abrumadora por la que no pueda (como “solo usar funciones definidas por el estándar C”, y sí, el código C11 puede ser de subprocesos múltiples). Que es básicamente lo que también dice el párrafo inicial de esta respuesta.

Para mí, esta línea a continuación fue suficiente para decidir:

La función sigaction() proporciona un mecanismo más completo y confiable para controlar señales; las nuevas aplicaciones deberían usar sigaction() en lugar de signal()

http://pubs.opengroup.org/onlinepubs/009695399/functions/signal.html#tag_03_690_07

Ya sea que esté comenzando desde cero o modificando un programa antiguo, sigaction debería ser la opción correcta.

Son diferentes interfaces para las instalaciones de señal del sistema operativo. Uno debería preferir usar sigaction para señalar si es posible, ya que signal() tiene un comportamiento definido por la implementación (a menudo propenso a la carrera) y se comporta de manera diferente en Windows, OS X, Linux y otros sistemas UNIX.

Consulte esta nota de seguridad para obtener más información.

valoraciones y reseñas

Eres capaz de añadir valor a nuestra información cooperando tu experiencia en las interpretaciones.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

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