2011-03-12 24 views
9

Tengo un programa simple en Linux que envía la señal SIGUSR1 a su proceso hijo en un ciclo. Pero cuando envío, p. A veces, 10 señales indican que el niño recibió solo 3 de ellas. La última señal enviada es siempre SIGUSR2 y se recibe siempre.puesta en cola de señales en C

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

Respuesta

12

Lo que ocurre es lo siguiente:

  1. primera señal recibida, es decir SIGUSR1, gestor se llama y se está ejecutando
  2. segunda señal recibida, dado que el manejador de nr1 aún se está ejecutando, la señal nr2 queda pendiente y bloqueada.
  3. Tercera señal recibida, dado que el controlador de nr1 todavía está en ejecución, la señal 3 se descarta.
  4. Cuarta, quinta ... señal del mismo tipo que la señal nr1 son descartadas.

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

Básicamente, las señales pendientes del mismo tipo no están en cola, sino que se descartan. Y no, no hay una manera fácil de "explotar" enviar señales de esa manera. Uno siempre asume que puede haber varias señales que se descartan e intenta que el controlador haga el trabajo de limpiar y descubrir qué hacer (como cosechar hijos, si todos los niños mueren al mismo tiempo).

+1

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

6

Si se envían y no se manejan varias señales del mismo tipo, no están en cola. Digamos que el programa enmascara SIGUSR1, llama al kill(getpid(), SIGUSR1) 10 veces y desenmascara SIGUSR1. Recibirá SIGUSR1 solo una vez.

1

Por lo tanto, hacer E/S simultáneas de muchos archivos con SIGIO parece posible solo si se usa el indicador SA_NODEFER para el campo struct sigaction sa_flags y nunca se bloquean las señales.

Entonces, uno podría obtener una interrupción desde dentro de un manejador de señal y crear un nuevo hilo para cada señal individual que se maneja. Eso se complica :) Así que no me pregunto por qué nadie parece usar SIGIO.