2010-09-28 35 views
10

Este es un escenario bastante básico, pero no encuentro demasiados recursos útiles. Tengo un programa C++ ejecutándose en Linux que procesa archivos. Lee líneas, realiza varias transformaciones, escribe datos en una base de datos. Hay ciertas variables (almacenadas en la base de datos) que afectan el procesamiento que estoy leyendo en cada iteración porque quiero que el procesamiento sea lo más actualizado posible, pero un ligero retraso está bien. Pero esas variables cambian muy raramente, y las lecturas son costosas a lo largo del tiempo (10 millones más filas por día). Podría espaciar las lecturas a cada n iteraciones o simplemente reiniciar el programa cuando una variable cambia, pero esas parecen hackish.Manejo básico de señales en C++

Lo que me gustaría hacer es hacer que el programa active una nueva lectura de las variables cuando recibe un SIGHUP. Todo lo que estoy leyendo sobre el manejo de señales está hablando de la biblioteca de señales C, que no estoy seguro de cómo vincular las clases de mi programa. Las bibliotecas de señales de Boost parecen tener más que ver con la comunicación entre objetos en lugar de manejar las señales del sistema operativo.

¿Alguien puede ayudar? Parece que esto debería ser increíblemente simple, pero estoy bastante oxidado con C++.

Respuesta

15

Lo manejaría igual que podría manejarlo en C. Creo que está perfectamente bien tener una función de controlador de señal independiente, ya que solo estará publicando en un semáforo o estableciendo una variable o algo más, que otro hilo u objeto puede inspeccionar para determinar si necesita volver a leer la configuración.

#include <signal.h> 
#include <stdio.h> 

/* or you might use a semaphore to notify a waiting thread */ 
static volatile sig_atomic_t sig_caught = 0; 

void handle_sighup(int signum) 
{ 
    /* in case we registered this handler for multiple signals */ 
    if (signum == SIGHUP) { 
     sig_caught = 1; 
    } 
} 

int main(int argc, char* argv[]) 
{ 
    /* you may also prefer sigaction() instead of signal() */ 
    signal(SIGHUP, handle_sighup); 

    while(1) { 
     if (sig_caught) { 
      sig_caught = 0; 
      printf("caught a SIGHUP. I should re-read settings.\n"); 
     } 
    } 

    return 0; 
} 

Usted puede probar el envío de un SIGHUP utilizando kill -1 `pidof yourapp`.

+1

Oh duh. Estaba pensando demasiado y olvidé que las variables de señal son lo que quiero en lugar de la invocación directa. * headdesk * – KernelM

+4

Si quiere cumplir con los estándares, asegúrese de calificar su manejador de señal como 'extern' C "' –

+0

@R Samuel: Es un gran punto.Ni siquiera pensé en 'extern" C "' ya que estaba escribiendo código C, ¡pero el OP lo necesitará! –

1

Hay varias posibilidades; no sería necesariamente excesivo implementarlos a todos:

  • Responda a una señal específica, como C lo hace. C++ funciona de la misma manera. Consulte la documentación para signal().
  • Dispare la fecha y hora de modificación de algunos cambios de archivo, como la base de datos si está almacenada en un archivo plano.
  • Disparador una vez por hora o una vez por día (lo que tenga sentido).
3

Recomiendo retirar this link que proporciona los detalles sobre el registro de una señal.

A menos que me equivoque, una cosa importante para recordar es que cualquier función dentro de un objeto espera un parámetro referente, lo que significa que las funciones miembro no estáticas no pueden ser manejadores de señal. Creo que deberás registrarlo en una función miembro estática o en algún tipo de función global. A partir de ahí, si tiene una función de objeto específica que desea encargarse de su actualización, necesitará una forma de referenciar ese objeto.

+0

Ese sitio web parece cerrado, por lo que es posible que desee consultar [este enlace] (http://www.yolinux.com/TUTORIALS/C++Signals.html) para obtener más información. –

+0

No, cplusplus.com (y ese enlace) todavía parece estar bien para mí. Siempre es bueno tener múltiples referencias sin embargo. – Bryan

0

Puede definir una señal de Boost correspondiente a la señal del sistema operativo y vincular la señal de Boost a su ranura para invocar al controlador respectivo.