Actualizado el 21 de Noviembre del 2020 (Publicado el 14 de Enero del 2017)
1.493 visualizaciones desde el 14 de Enero del 2017
69,4 KB
10 paginas
Creado hace 11a (14/10/2013)
Master en Computación
Programación Concurrente
Bloque II: Programación concurrente en POSIX
Introducción al estándar POSIX
Tema 1.
Tema 2. Sistema Operativo MaRTE OS
Tema 3. Gestión de Threads
Tema 4. Gestión del Tiempo
Tema 5. Planificación de Threads
Tema 6. Sincronización
Tema 7. Señales
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
Programación Concurrente
© M. Aldea, M. González
oct-13
1
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
Tema 8. Temporizadores y Relojes de Tiempo de
Ejecución
8.1. Concepto de temporizador
8.2. Notificación de Eventos
8.3. Funciones para manejar temporizadores
8.4. Ejemplo: Threads Periódicos con temporizadores
8.5. Relojes y temporizadores de tiempo de ejecución
8.6. Ejemplo: limitación del tiempo de ejecución
8.7. Relojes de tiempo de ejecución para grupos de threads
8.8. Gestión de eventos temporales en MaRTE OS
Programación Concurrente
© M. Aldea, M. González
oct-13
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.1 Concepto de temporizador
Temporizador:
8.1 Concepto de temporizador
• un objeto que puede notificar a un proceso si ha transcurrido
un cierto intervalo de tiempo o se ha alcanzado una hora
determinada
• cada temporizador está asociado a un reloj
Programación Concurrente
© M. Aldea, M. González
oct-13
2
3
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.2 Notificación de Eventos
8.2 Notificación de Eventos
POSIX define un mecanismo para especificar el tipo de
notificación deseada, que es común a varios servicios:
• finalización de I/O asíncrona, expiración de un temporizador,
llegada de un mensaje
El tipo de notificación deseado se especifica mediante una
estructura sigevent
• el envío de una señal es uno de los tres posibles tipos de
notificación que es posible indicar con esta estructura:
- no hay notificación (SIGEV_NONE)
- se genera una señal (SIGEV_SIGNAL)
- se crea un thread y se ejecuta (SIGEV_THREAD) (no soportado
en MaRTE OS)
8.2 Notificación de Eventos
Programación Concurrente
© M. Aldea, M. González
oct-13
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
Campos de la estructura sigevent
struct sigevent {
int sigev_notify;
// Notificación: SIGEV_NONE, SIGEV_SIGNAL o
// SIGEV_THREAD
int sigev_signo;
// Número de señal a enviar (SIGEV_SIGNAL)
union sigval sigev_value;
// Valor asociado a la señal (SIGEV_SIGNAL)
// o argumento para el thread (SIGEV_THREAD)
void (*sigev_notify_function)(union sigval);
// Cuerpo del thread (SIGEV_THREAD)
pthread_attr_t *sigev_notify_attributes;
// Atributos del thread (SIGEV_THREAD)
};
4
5
Programación Concurrente
© M. Aldea, M. González
oct-13
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.3 Funciones para manejar temporizadores
8.3 Funciones para manejar temporizadores
• Crear un temporizador:
#include <signal.h>
#include <time.h>
int timer_create (clockid_t clock_id,
struct sigevent *evp,
timer_t *timerid);
• crea un temporizador asociado al reloj clock_id
• *evp indica la notificación deseada: ninguna, enviar una señal
con información, o crear y ejecutar un thread
• en *timerid se devuelve el identificador del temporizador
• el temporizador se crea en estado “desarmado”
• el temporizador es visible para el proceso que lo creó
• Borrar un temporizador
int timer_delete (timer_t timerid);
Programación Concurrente
© M. Aldea, M. González
oct-13
6
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.3 Funciones para manejar temporizadores
Armar un temporizador
Se utiliza la función:
int timer_settime (timer_t timerid, int flags,
const struct itimerspec *value,
struct itimerspec *ovalue);
struct itimerspec {
struct timespec it_value; // primera expiración
struct timespec it_interval; // periodo entre
} // sucesivas expiraciones
• si value.it_value = 0 el temporizador se desarma
• si value.it_value > 0 el temporizador se arma, y su valor se
hace igual a value
- si el temporizador ya estaba armado, se rearma
• si value.it_interval > 0 el temporizador es periódico
después de la primera expiración
Programación Concurrente
© M. Aldea, M. González
oct-13
7
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
Armar un temporizador
8.3 Funciones para manejar temporizadores
(cont.)
• flag indica si el temporizador es absoluto o relativo:
- si TIMER_ABSTIME se especifica, la primera expiración será
cuando el reloj valga value.it_value
- si no se especifica, la primera expiración será cuando
transcurra un intervalo igual a value.it_value
• cada vez que el temporizador expira, se envía la notificación
solicitada en *evp al crearlo
• si ovalue no es NULL se devuelve el valor anterior
Programación Concurrente
© M. Aldea, M. González
oct-13
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
Leer el estado de un temporizador
8.3 Funciones para manejar temporizadores
• Leer el valor de un temporizador:
int timer_gettime (timer_t timerid,
struct itimerspec *value);
• significado del valor retornado en value:
- value.it_value: tiempo que falta para que expire
- value.it_interval: periodo del temporizador
• Leer el número de expiraciones no notificadas:
int timer_getoverrun (timer_t timerid);
• el temporizador sólo mantiene una señal pendiente, aunque
haya muchas expiraciones
• el número de expiraciones no notificadas se puede saber
mediante esta función
Programación Concurrente
© M. Aldea, M. González
oct-13
8
9
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.4 Ejemplo: Threads Periódicos con temporizadores
8.4 Ejemplo: Threads Periódicos con
temporizadores
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <unistd.h>
#include <misc/error_checks.h>
struct periodic_data {
struct timespec per;
int sig_num;
};
Programación Concurrente
© M. Aldea, M. González
oct-13
10
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.4 Ejemplo: Threads Periódicos con temporizadores
Ejemplo: Threads Periódicos con temporizadores (cont.)
// Thread periódico que crea un temporizador periódico
void * periodic (void *arg)
{
struct periodic_data my_data;
int received_sig;
struct itimerspec timerdata;
timer_t timer_id;
struct sigevent event;
sigset_t set;
my_data = * (struct periodic_data*)arg;
// crea el temporizador
event.sigev_notify = SIGEV_SIGNAL;
event.sigev_signo = my_data.sig_num;
CHKE( timer_create(CLOCK_MONOTONIC, &event, &timer_id) );
// programa el temporizador (expiración periódica)
timerdata.it_interval = my_data.per;
timerdata.it_value = my_data.per;
CHKE( timer_settime(timer_id, 0, &timerdata, NULL) );
Programación Concurrente
© M. Aldea, M. González
oct-13
11
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.4 Ejemplo: Threads Periódicos con temporizadores
Ejemplo: Threads Periódicos con temporizadores (cont.)
// conjunto de señales esperadas por sigwaitinfo
sigemptyset (&set);
sigaddset(&set,my_data.sig_num);
// La mascara de señales vendrá fijada por el padre
// espera la expiración del temporizador y realiza el trabajo útil
while (1) {
CHKE( sigwait(&set, &received_sig) );
printf("Thread con periodo sec=%d nsec=%d activo \n",
my_data.per.tv_sec,my_data.per.tv_nsec);
}
}
Programación Concurrente
© M. Aldea, M. González
oct-13
12
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.4 Ejemplo: Threads Periódicos con temporizadores
Ejemplo: Threads Periódicos con temporizadores (cont.)
// Programa principal, que crea dos threads periódicos
int main() {
pthread_t t1,t2;
sigset_t set;
struct periodic_data per_params1,per_params2;
// pone la máscara de señales
sigemptyset(&set);
sigaddset(&set, SIGRTMIN);
sigaddset(&set, SIGRTMIN+1);
CHK( pthread_sigmask(SIG_BLOCK, &set, NULL) );
// crea el primer thread
per_params1.per.tv_sec = 0; per_params1.per.tv_nsec = 500000000;
per_params1.sig_num = SIGRTMIN;
CHK( pthread_create (&t1, NULL, periodic, &per_params1) );
// crea el segundo thread
per_params2.per.tv_sec = 1; per_params2.per.tv_nsec = 500000000;
per_params2.sig_num = SIGRTMIN+1;
CHK( pthread_create (&t2, NULL, periodic, &per_params2) );
sleep(30);
exit(0);
}
Programación Concurrente
© M. Aldea, M. González
oct-13
13
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.5 Relojes y temporizadores de tiempo de
8.5 Relojes y temporizadores de tiempo de ejecución
ejecución
Se asocian tanto a procesos como a threads:
• permiten monitorizar el tiempo de ejecución o de CPU
- todas las técnicas de análisis de tiempo real se basan en los
tiempos de ejecución de peor caso
• permiten detectar un consumo excesivo de tiempo de CPU
- mediante la interfaz de temporizadores
- cuando un temporizador expira, envía una señal
Esta limitación de tiempos de ejecución era habitual en los
ejecutivos cíclicos
Los temporizadores de tiempo de CPU permiten el mismo grado de
fiabilidad en sistemas POSIX
Programación Concurrente
© M. Aldea, M. González
oct-13
14
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.5 Relojes y temporizadores de tiempo de ejecución
Interfaz para relojes de tiempo de CPU
Constantes del tipo clockid_t que identifican el reloj del thread o
proceso actual:
CLOCK_THREAD_CPUTIME_ID
CLOCK_PROCESS_CPUTIME_ID
Funciones para obtener el identificador de reloj de un proceso o
thread cualquiera:
#include <pthread.h>
#include <time.h>
int clock_getcpuclockid(pid_t pid,
clockid_t *clock_id);
int pthread_getcpuclockid(pthread_t thread_id,
clockid_t *clock_id);
Programación Concurrente
© M. Aldea, M. González
oct-13
15
Tema 8. Temporizadores y Relojes de Tiempo de Ejecución
8.6 Ejemplo: limitación del tiempo de ejecución
8.6 Ejemplo: limitación del tiempo de ejecución
#inc
Comentarios de: Programación Concurrente - Bloque II: Programación concurrente en POSIX - Tema 8. Temporizadores y Relojes de Tiempo de Ejecución (0)
No hay comentarios