Colas de señal en C

3 minutos de lectura

avatar de usuario
Pedro Krejci

Tengo un programa simple bajo Linux que envía la señal SIGUSR1 a su proceso secundario en un ciclo. Pero cuando envío, por ejemplo, 10 señales, a veces sucede que el niño recibió solo 3 de ellas. La última señal enviada siempre es SIGUSR2 y se recibe siempre.

¿Están las señales en cola, o cuando el proceso no procesó el anterior, simplemente se sobrescribe? ¿Hay alguna manera de enviar señales en una cola?

avatar de usuario
Milán

Lo que pasa es lo siguiente:

  1. Se recibe la primera señal, a saber, SIGUSR1, se llama al controlador y se está ejecutando
  2. Se recibió la segunda señal, dado que el controlador de nr1 aún se está ejecutando, la señal nr2 queda pendiente y bloqueada.
  3. Se recibió la tercera señal, dado que el controlador de nr1 aún se está ejecutando, la señal 3 se descarta.
  4. Se descartan señales cuarta, quinta… etc. del mismo tipo que la señal nr1.

Una vez que el controlador de señales haya terminado con la señal nr1, procesará la señal nr2 y luego el controlador de señales procesará SIGUSR2.

Básicamente, las señales pendientes del mismo tipo no se ponen en cola, sino que se descartan. Y no, no hay una manera fácil de “ráfagas” de enviar señales de esa manera. Uno siempre asume que puede haber varias señales que se descartan, y trata de dejar que el manejador haga el trabajo de limpiar y averiguar qué hacer (como cosechar niños, si todos los niños mueren al mismo tiempo).

  • Muchas gracias, ese era el problema. Entonces, mi solución es que después de cada SIGUSR1 recibido en el proceso secundario, respondo con SIGUSR2 y el proceso principal no enviará otro SIGUSR1 antes de recibir la confirmación SIGUSR2 del niño. ¡Y parece funcionar! Gracias una vez más:)

    -Peter Krejci

    12 de marzo de 2011 a las 22:52

avatar de usuario
kubi

Si se envían varias señales del mismo tipo y no se gestionan, no se ponen en cola. Di las máscaras del programa SIGUSR1llamadas kill(getpid(), SIGUSR1) 10 veces y desenmascara SIGUSR1. recibirá SIGUSR1 sólo una vez.

Su problema es probablemente que SIGUSR2 es una señal que se entrega de inmediato, mientras que otras señales están bloqueadas o en cola (en estado pendiente).

Así es como puede verificar las señales pendientes: http://www.gnu.org/s/libc/manual/html_node/Checking-for-Pending-Signals.html

avatar de usuario
Sami Kivisto

Entonces, hacer E/S simultáneas de muchos archivos con SIGIO parece posible solo si uno usa flag SA_NODEFER para seguir la estructura sa_flags campo y nunca bloquea las señales.

Entonces, uno podría obtener una interrupción desde el interior de un controlador de señal y crear un nuevo hilo para cada señal individual que se maneja. Eso se complica 🙂 Así que no es de extrañar por qué nadie parece usar SIGIO.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad