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);
}