Compartir vía


Usar un temporizador del sistema como perrito de vigilancia

Una aplicación de alto nivel puede utilizar un temporizador del sistema como un guardián para hacer que el sistema operativo termine y reinicie la aplicación si no responde. Cuando el perro de vigilancia expira, genera una señal de que la aplicación no maneja, lo que a su vez hace que el sistema operativo termine la aplicación. Después de la finalización, el sistema operativo reinicia automáticamente la aplicación.

Para usar un temporizador de perros guardianes:

  • Definir el temporizador
  • Crear y armar el temporizador
  • Restablecer el temporizador periódicamente antes de que expire

Para definir el temporizador, cree una estructura itimerspec y establezca el intervalo y la expiración inicial en un valor fijo, como un segundo.

#include <time.h>

const struct itimerspec watchdogInterval = { { 1, 0 },{ 1, 0 } };
timer_t watchdogTimer;

Establece un evento de notificación, una señal y un valor de señal para el perro vigilante, llama a timer_create para crearlo y llama a timer_settime para armarlo. En este ejemplo, watchdogTimer genera el evento SIGALRM. La aplicación no controla el evento, por lo que el sistema operativo finaliza la aplicación.

void SetupWatchdog(void)
{
    struct sigevent alarmEvent;
    alarmEvent.sigev_notify = SIGEV_SIGNAL;
    alarmEvent.sigev_signo = SIGALRM;
    alarmEvent.sigev_value.sival_ptr = &watchdogTimer;

    int result = timer_create(CLOCK_MONOTONIC, &alarmEvent, &watchdogTimer);
    result = timer_settime(watchdogTimer, 0, &watchdogInterval, NULL);
}

En cualquier otro lugar del código de aplicación, restablezca periódicamente al guardián. Una técnica es utilizar un segundo temporizador, que tiene un período más corto que el watchdogInterval, para verificar que la aplicación está funcionando según lo esperado y, si es así, restablecer el temporizador de vigilancia.

// Must be called periodically
void ExtendWatchdogExpiry(void)
{
    //check that application is operating normally
    //if so, reset the watchdog
    timer_settime(watchdogTimer, 0, &watchdogInterval, NULL);
}