No puede confiar en que se entregarán todas las señales enviadas. Por ejemplo, el kernel de Linux "fusiona" SIGCHLD si un proceso tarda mucho en manejar SIGCHLD desde un proceso hijo salido.
Para responder otra parte de su pregunta, las señales se "ponen en cola" dentro del núcleo si llegan varias señales diferentes en un intervalo demasiado corto.
Debe usar sigaction()
para configurar el controlador de señal con el sa_sigaction
miembro de siginfo_t
, estableciendo el sa_mask
miembro del siginfo_t
argumento con cuidado. Creo que esto significa enmascarar todas las señales "asíncronas" al menos. Según la página del manual para Linux sigaction()
, también ocultará la señal que se está manejando. Creo que debería establecer el sa_flags
miembro en SA_SIGINFO, pero no recuerdo por qué tengo esta superstición. Creo que esto le dará a su proceso un controlador de señal que se mantiene sin condiciones de carrera, y que no se ve interrumpido por la mayoría de las otras señales.
Escriba su función de controlador de señal con mucho, mucho cuidado. Básicamente, establezca una variable global para indicar que se atrapó una señal y haga que el resto del proceso se ocupe de la acción deseada para esa señal. Las señales se enmascararán por la menor cantidad de tiempo de esa manera.
Además, querrá probar su código de manejo de señal muy a fondo. Póngalo en un pequeño proceso de prueba y envíe tantas señales SIGUSR1 y SIGUSR2 como sea posible, tal vez desde 2 o 3 programas de envío de señales de propósito especial. Mezcle también algunas otras señales, después de que esté seguro de que su código puede manejar SIGUSR1 y SIGUSR2 de manera rápida y correcta. Prepárese para la depuración difícil.
Si usa Linux y solo Linux, puede pensar en usarlo signalfd()
para crear un descriptor de archivo que pueda select()
o sondear para recibir esas señales. El uso signalfd()
podría facilitar la depuración.
signal(2)
sugiere enfáticamente que evite esta confusión al usar en susigaction(2)
lugar.