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.
- 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. - los
signal()
La función (generalmente) restablece la acción de la señal de nuevo aSIG_DFL
(predeterminado) para casi todas las señales. Esto significa que elsignal()
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). - 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()
osigqueue()
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 comovolatile sig_atomic_t
o 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.