2011-06-03 15 views
12

La programación Linux Interfaz libro ha mencionado un método para tratar con señales asíncronas en un multi programa de roscado:trata de señales asíncronas en multihilo Programa

  • Todas las roscas bloquear todas las señales asíncronas que el proceso de podría recibir. La forma más sencilla de hacer es bloquear las señales en el hilo principal antes de crear cualquier otra cadena . Cada subproceso creado posteriormente heredará una copia de la máscara de señal del subproceso principal .
  • crea una única secuencia dedicada que acepta señales entrantes usando sigwaitinfo(), sigtimedwait() o sigwait().

La ventaja de este enfoque es que señales generadas de forma asíncrona son recibieron de forma sincrónica. Como acepta señales entrantes, la secuencia dedicada puede modificar de forma segura las variables compartidas (bajo control mutex) y llamar a funciones no asíncronas. También puede variables de condición de señal, y emply otro hilo y comunicación de proceso y mecanismos de sincronización.

Ahora las preguntas:

  1. cuando kernel quiere entregar señales que elegir uno de los hilos dentro de proceso arbitrario. desde donde puede saber para entregar la señal al hilo dedicado?
  2. pthread API es funciones no seguras para aync. Entonces, ¿cómo podemos usarlos dentro de manejador de señal?

Respuesta

8

Cuando el kernel proporciona una señal de proceso dirigida, elige uno de los hilos que no tienen la señal bloqueada. Esto significa que nunca elige ninguno de los hilos aparte del hilo de manejo de señal (que actúa como si tuviera la señal desbloqueada mientras estaba bloqueada en sigwaitinfo() o similar).En otras palabras: el kernel sabe dónde enviar la señal, porque ha arreglado cosas tales que el hilo de manejo de señal es el único hilo al que se le permite entregar la señal.

Hace no utilice la API pthreads, o cualquier función que no sea de señal asíncrona segura en un manejador de señal. La solución descrita no maneja las señales dentro de los manejadores de señal: maneja las señales dentro del flujo de ejecución normal del hilo de manejo de señal, después de que devuelve sigwaitinfo(). Esto le permite acceder a funciones que no son de señal asíncrona, que es el punto completo.

3

Recuerde que la propuesta es bloquear la señal (usando pthread_sigmask()) al principio de la ejecución del proceso, antes de engendrar hilos o recibir señales.

para responder a sus preguntas:

  1. Leer la página del manual de sigwait() (y/o sigwaitinfo()). Cuando el kernel quiere enviar una señal al proceso, pero todo el hilo tiene la señal bloqueada, la señal se pone en "cola". Permanece en cola hasta que (a) algún hilo desbloquea la señal; o (b) algunas llamadas de subproceso sigwait() o sigwaitinfo() en la señal. La propuesta aquí es dedicar un hilo para hacer lo último.

  2. La idea es que nunca ejecute controladores de señales, ya que ningún hilo desbloquea la señal. En cambio, un hilo espera la señal con sigwait(), y luego procesa la señal. Todo esto sucede fuera de del contexto de manejo de señal, que es la belleza de la propuesta.

+0

Sigaction no se usa para bloquear señales, vea sigprocmask y pthread_sigmask. –

+0

@ToddFreed: Créalo o no, eso es realmente lo que quise decir ... Corregido; Gracias – Nemo

0

Puede llamar indirectamente las API pthread desde un manejador de señales utilizando otro mecanismo. En el hilo principal, cree un socket de dominio Unix que escuche ciertos comandos. El manejador de señal puede tener código para conectarse al socket y enviar comandos al hilo principal para llamar a la API pthread que desea llamar.