2011-12-13 11 views
8

Estoy en una situación en la que necesito leer un árbol de búsqueda binaria (BST) dentro de un manejador de señal (SIGSEGV controlador de señal, que según mi conocimiento es por subproceso base). El BST puede ser modificado por los otros hilos en la aplicación.Lectura de datos compartidos dentro de un controlador de señal

Ahora que un manejador de señal no puede usar semáforos, mutexes etc. y por lo tanto no puede acceder a los datos compartidos, ¿Cómo resuelvo este problema? Tenga en cuenta que mi aplicación es multiproceso y se ejecuta en un sistema multinúcleo.

+5

Intentaré realmente, realmente difícil, pensar en una forma de no leer datos compartidos en ese manejador de señal. – dbeer

+1

Para enfatizar el punto de @dbeer, en un manejador de señal generalmente no debe hacer nada que bloqueará o generará otras señales, o cualquier operación prolongada. Un manejador de señal debe ser pequeño, rápido y corto. –

+1

Quizás me falta algo, pero si solo los hilos de su programa acceden a la memoria compartida (sin otras interrupciones y excepciones), ¿por qué no podría usar un semáforo (si el buen estilo es una pregunta diferente)? Si un hilo accede a la región crítica, la bloquea, se pone a dormir por otro hilo, el semáforo sigue bloqueado para el otro hilo y, finalmente, su hilo inicial se programará para acceder de nuevo. Dejando a un lado las razones de rendimiento, no veo peligro de corrupción de datos ni estancamiento del sistema. – gnometorule

Respuesta

3

Suponiendo que el SH no pueden acceder directamente a los datos compartidos, entonces tal vez usted podría hacerlo indirectamente:

  1. Tiene alguna variable global que sólo los gestores de señales pueden escribir, pero se pueden leer desde otro lugar (incluso si solo dentro del mismo hilo).
  2. SH establece el indicador cuando se invoca
  3. Los hilos sondean esta bandera cuando no están en el medio de la modificación de la BST; cuando lo encuentre, realizará el procesamiento requerido por la señal original (usando las sincronizaciones que sean necesarias), y luego emitirá una señal diferente (como SIGUSR1) para indicar que el procesamiento está hecho
  4. SH para esa señal restablece la bandera

Si le preocupa la superposición de SIGSEGV, agregue un contador a la mezcla para realizar un seguimiento. (¡Hola! ¡Acabas de crear tu propio semáforo!)

El eslabón débil aquí es obviamente el sondeo, pero es un comienzo.

+0

Estaba pensando exactamente lo mismo :-p! Pero lo que sucederá cuando un hilo esté modificando la BST cuando se produce la señal. Ese punto es un poco preocupante. – MetallicPriest

+0

Creo que eso no sería un problema: la señal quedará atrapada, configurará la bandera y regresará; el hilo continuará modificando el BST, y no intentará "manejar" la señal hasta que se termine con su modificación. Suponiendo que tales modificaciones sean atómicas, parece un resultado razonable. –

1

Puede considerar mmap -es un sistema de archivos fuse (en el espacio de usuario).

En realidad, usted será más feliz en Gnu Hurd que tiene soporte para external pagers

Y tal vez su truco de la lectura de un árbol binario de búsqueda en su manejador de señales a menudo podría funcionar en la práctica, no forma portátil y en un núcleo modo dependiente de la versión. Quizás el acceso de serialización con trucos no portátiles de bajo nivel (por ejemplo, futexes y atomic gcc builtins) podría funcionar. Leer el código fuente (específico de la máquina) de NPTL, es decir, las rutinas pthread de Linux actuales debería ayudar.

Probablemente sea el caso que pthread_mutex_lock etc. se puedan utilizar desde dentro de un manejador de señal Linux ... (porque probablemente solo haga futex e instrucciones atómicas).

+0

Mencioné algunos trucos no portátiles y Gnu hurd ... –

3

veo dos soluciones bastante limpio:

  1. específicas para Linux: Crear un dedicado señales de manipulación de hilo. Capture señales usando signalfd(). De esta forma manejarás las señales en un hilo común, no en ningún controlador limitado.
  2. Portátil: también use una secuencia dedicada que duerma hasta que se reciba la señal. Puede usar un tubo para crear un par de descriptores de archivo. El hilo puede leer (2) del primer descriptor y en un controlador de señal puede escribir (2) en el segundo descriptor. El uso de write() en un manejador de señal es legal de acuerdo con POSIX. Cuando el hilo lee algo de la tubería, sabe que debe realizar alguna acción.
Cuestiones relacionadas