jueves, 6 de febrero de 2014

Temporizadores y tareas periódicas

Un temporizador se trata de un registro contador asociado a un reloj. Una vez creado se inicializa con el tiempo a contar y cada pulso de reloj decrementa el contador del temporizador. Al llegar a 0 se envía una señal al proceso que lo creó e inicializa de nuevo su valor.

Creación de un temporizador

#includes <sys/time.h>

int timer_create (clockid_t clock_id, struct sigevent *evp, timer_t *timerid)

int timer_settime (timer_t timerid, int flags, const struct itimerspec *value, struct itimerspec *ovalue);

Devuelve 0 en caso de éxito y -1 en caso de error. Es importante definir un identificador para el temporizador y el tipo de notificación que se produce cuando expira el temporizador. NULL eleva SIGALARM.

struct sigevent {  
   int sigev_notify /* notification type */ 
   int sigev_signo; /* signal number */  
   union sigval sigev_value; /* signal value */ 
};

sigev_notify
   SIGEV_SIGNAL : Se asocia una señal.
   SIGEV_NONE : No se notifica nada.

El valor de espera se especifica mediante una estructura de tipo itimerspec.
  • it_value: valor inicial del temporizador (0 lo desactiva).
  • it_interval: nuevo valor tras expiración (0 un solo evento).
struct itimerspec {    
   struct timespec it_interval; /* periodo */    
   struct timespec it_value; /* valor inicial*/ 
};  

struct timespec {   
   time_t tv_sec; /* seconds */    
   long tv_nsec; /* and nanoseconds */ 
}; 


Tarea periódica

Los temporizadores por sí solos no tienen mucha función, por ello añadimos las tareas periódicas.


void periodic (void *arg) {  
   int signum; /* señal recibida */  
   sigset_t set; /* señales a las que se espera */  
   struct sigevent sig; /* información de señal */  
   timer_t timer;  
   struct itimerspec required, old;  
   struct timespec first, period;  

   sig.sigev_notify = SIGEV_SIGNAL;  
   sig.sigev_signo = SIGRTMIN;  
   
   if (clock_gettime (CLOCK_MONOTONIC, &first) != 0) error();   

   first.tv_sec = first.tv_sec + 1;  
   period.tv_sec = 0;  
   period.tv_nsec = 10.0E6; /* 10 ms */  
   required.it_value = first;  
   required.it_interval = period;


   if (timer_create(CLOCK_MONOTONIC,&sig,&timer) != 0) error();  
   if (sigemptyset(&set) != 0) error ();  
   if (sigaddset(&set, SIGRTMIN) != 0) error();  
   if (timer_settime(timer,0, &required, &old) != 0)    error ();  
   
   while (1) {  
      if (sigwait(&set, &signum) != 0) error();   // Comportamiento de la tarea 
   }
}


Ejecutivo cíclico

Si todas las tareas son periódicas, se puede confeccionar un plan fijo de ejecución. No se utiliza la concurrencia, por lo que las distintas tareas se simulan en un programa secuencial, sin soporte del lenguaje o del sistema operativo.

No hay comentarios:

Publicar un comentario