Los mecanismos de temporizador le permiten programar el kernel del sistema operativo para notificar a una aplicación cuando haya transcurrido un tiempo predeterminado. Por lo general, los usará proporcionando dos piezas de información. Primero, deberá especificar cuánto tiempo debe tomar el temporizador antes de notificar. En segundo lugar, deberá preparar una función de devolución de llamada para actuar cuando se produzca esa notificación.
Enfoque tradicional de los temporizadores
Los mecanismos de temporizador en los sistemas basados en Linux y Unix han evolucionado para satisfacer diversas necesidades. Diferentes enfoques pueden ayudarlo a resolver diferentes tipos de problemas. Sin embargo, a menudo verá la primera versión del alarma() mecanismo aún en uso.
La función de alarma es la forma más sencilla de utilizar un temporizador; aquí está su prototipo:
no firmadoEn talarma(no firmadoEn t segundos);
Con este método, solo puede especificar el tiempo en segundos completos. Cuando se acaba el tiempo, el sistema operativo envía el
SIGALRM señal a su aplicación. Para procesar la caducidad del temporizador en su aplicación, también debe definir una función de devolución de llamada.Aquí hay un ejemplo de una función de controlador de señal:
#incluir
#incluir
#incluir
#incluirvacíotimer_callback(En t señal)
{
tiempo_t ahora = tiempo(NULO);
imprimir("Señal %d captada en %li", señal, ahora);
}
En tprincipal()
{
señal (SIGALRM, timer_callback);
alarma(1);
dormir(3);
devolver0;
}
Este código plantea una SIGALRM señal después 1 segundo. Si desea aumentar la demora del temporizador a cinco segundos, simplemente llame alarma (5) en cambio. Para detener el temporizador, pase un valor de 0: alarma (0).
Cuando se acabe el tiempo, el temporizador que utilice no se reiniciará periódicamente. Por ejemplo, si desea retrasar un segundo más, debe reiniciar el mecanismo con otra llamada a alarma().
A pesar de su facilidad de uso, este método tiene algunas desventajas:
- Sólo un temporizador a la vez.
- Sin soporte de temporizador periódico.
- Solo puede dar el período de tiempo en múltiplos de segundos enteros.
- No hay forma de saber cuánto tiempo queda en un temporizador.
Guarde el código de muestra anterior como alarma.c. Cuando compilas y ejecutas él, el programa llamará al timer_callback función después de un segundo. A continuación, esperará los dos segundos restantes debido a la dormir (3) línea, luego terminar.
$ gcc -o alarma alarma.c
$ tiempo ./alarma
Señal 14 captada en 1653490465
reales 0m1.004s
usuario 0m0.000s
sistema 0m0.003s
La razón para usar el comando de tiempo es poder ver los tiempos. Pero si observa el resultado, el tiempo total de ejecución no es de tres segundos. Esto se debe a la SIGALRM señal de alarma (1) cuando el primer segundo ha terminado, mientras que el llamada al sistema causado por la función dormir (3) está funcionando. Cuando llega esta señal, interrumpe la llamada al sistema iniciada para dormir (3).
Usar un temporizador de intervalos
El mecanismo del temporizador de intervalos estuvo disponible por primera vez en la versión 4.2 BSD. fue más tarde estandarizado por POSIX. Sus principales ventajas frente a las tradicionales. alarma() método de temporizador basado son:
- Proporciona una resolución de microsegundos.
- Permite controlar la medida del tiempo con más detalle en tres modos diferentes.
- Es posible configurarlo una vez y hacerlo funcionar periódicamente.
- Es posible saber cuánto tiempo está presente en un momento dado.
Los prototipos de funciones utilizados para las operaciones del temporizador de intervalos son los siguientes:
#incluir
En tsetitimer(En t cual, constante struct itimerval *nuevoValor, struct itimerval *antiguoValor);
En tobtener(En t cual, estructura itimerval *valor);estructuraiterval
{
estructuratiempoitInterval;// siguiente valor
estructuratiempoesValor;// valor actual
};
estructuratiempo
{
largo tv_seg;
largo tv_usec;
};
Si desea configurar un temporizador de intervalos, deberá utilizar el iterval estructura Deberá pasar un valor usando esta estructura como el segundo argumento para el programar función.
Por ejemplo, un temporizador de intervalos que notificará a su aplicación durante 1 segundo y luego cada 300 milisegundos se puede configurar de la siguiente manera:
estructuraitervalnuevoTemporizador;
estructuraitervalviejo contador de tiempo;newTimer.itValue.tv_sec = 1;
nuevoTemporizador.itValue.tv_usec= 0;newTimer.itInterval.tv_sec = 0;
newTimer.itInterval.tv_usec = 300 * 1000;
setitimer (ITIMER_REAL, &newTimer, &oldTimer);
Si hay un temporizador de intervalos activo antes de que se establezcan los nuevos valores, sus valores se transfieren a la dirección variable del iterval tipo dado al tercer parámetro de la función.
Puede configurar tres tipos diferentes de temporizadores con el mecanismo del temporizador de intervalos. Especifique el tipo de temporizador en el primer parámetro de setitimer():
Tipo de temporizador | Señal | Explicación |
---|---|---|
ITIMER_REAL | SIGALRM | Independiente del tiempo empleado por la aplicación, calculado sobre el tiempo total transcurrido. |
ITIMER_VIRTUAL | SIGVTALRM | Calculado durante el tiempo que la aplicación se ejecuta solo en modo de usuario. |
ITIMER_PROF | SIGPROF | Calculado sobre la suma del tiempo empleado por la aplicación en modo usuario y sistema. |
Puede ver en esta tabla que el ITIMER_REAL tipo envía un SIGALRM señal, al igual que la alarma() función.
Usando un cronómetro de intervalos y alarma() en la misma aplicación será confuso. Aunque puede realizar una segunda comprobación del tiempo restante con gettimer(), no tiene sentido usarlos simultáneamente.
Aquí hay un ejemplo de cómo definir la función del controlador de señal con el encabezado de depuración:
#incluir
#incluir
#incluir
#incluir
#incluir
#incluir
#incluir
#incluir "./depuración.h"vacíotimer_callback(En t señal)
{
estructuratiempoahora;
gettimeofday(&ahora, NULO);
imprimir("Señal %d captada en %li.%03li ", signum, now.tv_sec, now.tv_usec / 1000);
}En tprincipal()
{
no firmadoEn t restante = 3;estructuraitervalnuevo_temporizador;
estructuraitervalviejo contador de tiempo;new_timer.it_value.tv_sec = 1;
new_timer.it_value.tv_usec = 0;
new_timer.it_interval.tv_sec = 0;
new_timer.it_interval.tv_usec = 300 * 1000;setitimer (ITIMER_REAL, &new_timer, &old_timer);
señal (SIGALRM, timer_callback);tiempo (dormir (restante) != 0)
{
si (errno == EINTR)
debugf("suspensión interrumpida por señal");
más
errorf("error de inactividad %s", strerror (errno));
}
devolver0;
}
El código anterior utiliza el dormir() Función para esperar tres segundos. Durante este tiempo, se ejecuta un temporizador de intervalos, primero durante un segundo, luego en un intervalo de 300 milisegundos.
Para una mejor comprensión, guarde y compile el código de ejemplo con el nombre intervalo.c:
$ gcc -o intervalo intervalo.c
$ tiempo ./intervalo
Señal 14 captada en 1653493614.325
depuración: suspensión interrumpida por señal (intervalo principal.c: 36)
Señal 14 captada en 1653493614.625
depuración: suspensión interrumpida por señal (intervalo principal.c: 36)
Señal 14 captada en 1653493614.925
depuración: suspensión interrumpida por señal (intervalo principal.c: 36)
Señal 14 captada en 1653493615.225
depuración: suspensión interrumpida por señal (intervalo principal.c: 36)
Señal 14 captada en 1653493615.525
...
Como puede ver en la salida después de que se ejecuta el temporizador, llama a la función de devolución de llamada cada 300 milisegundos.
Sin embargo, después de esperar un poco más, notará que la aplicación no finaliza. Continúa ejecutando la función de devolución de llamada cada 300 milisegundos. Si aumenta el valor del intervalo en milisegundos, verá que la aplicación finaliza. Esto se debe al área de uso del dormir() función.
Importancia de usar temporizadores en Linux
Especialmente para aplicaciones en tiempo real, el mecanismo del temporizador es de gran importancia. Esta es también una solución utilizada para optimizaciones de rendimiento. Incluso puede usarlo para medir el tiempo de actividad o la latencia en su aplicación. Es importante utilizar mecanismos de temporizador para realizar un seguimiento del tiempo transcurrido y los eventos de transición de tiempo.
Cómo compilar e instalar software desde la fuente en Linux
Leer siguiente
Temas relacionados
- Programación
- Programación
- Consejos Linux
Sobre el Autor

Ingeniero y desarrollador de software aficionado a las matemáticas y la tecnología. Siempre le ha gustado la informática, las matemáticas y la física. Ha desarrollado proyectos de motores de juegos, así como aprendizaje automático, redes neuronales artificiales y bibliotecas de álgebra lineal. Además continúa trabajando en aprendizaje automático y matrices lineales.
Suscríbete a nuestro boletín
¡Únase a nuestro boletín para obtener consejos técnicos, reseñas, libros electrónicos gratuitos y ofertas exclusivas!
Haga clic aquí para suscribirse