temporizador - implementar retraso de tiempo en c
tipos de funciones en c (12)
¿Es timer
?
Para WIN32, pruebe http://msdn.microsoft.com/en-us/library/ms687012%28VS.85%29.aspx
No sé exactamente cómo redactar una búsqueda para esto ... así que no he tenido suerte para encontrar algo ...: S
Necesito implementar un retraso de tiempo en C.
por ejemplo, quiero hacer algunas cosas, luego esperar, decir 1 minuto, luego continuar haciendo las cosas.
¿Eso tiene sentido? ¿Puede alguien ayudarme?
Así es como puede hacerlo en la mayoría de los sistemas de escritorio:
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
void wait( int seconds )
{ // Pretty crossplatform, both ALL POSIX compliant systems AND Windows
#ifdef _WIN32
Sleep( 1000 * seconds );
#else
sleep( seconds );
#endif
}
int
main( int argc, char **argv)
{
int running = 3;
while( running )
{ // do something
--running;
wait( 3 );
}
return 0; // OK
}
Aquí es cómo puedes hacerlo en un microordenador / procesador sin temporizador:
int wait_loop0 = 10000;
int wait_loop1 = 6000;
// for microprocessor without timer, if it has a timer refer to vendor documentation and use it instead.
void
wait( int seconds )
{ // this function needs to be finetuned for the specific microprocessor
int i, j, k;
for(i = 0; i < seconds; i++)
{
for(j = 0; j < wait_loop0; j++)
{
for(k = 0; k < wait_loop1; k++)
{ // waste function, volatile makes sure it is not being optimized out by compiler
int volatile t = 120 * j * i + k;
t = t + 5;
}
}
}
}
int
main( int argc, char **argv)
{
int running = 3;
while( running )
{ // do something
--running;
wait( 3 );
}
return 0; // OK
}
Las variables waitloop deben afinarse, las que funcionaron bastante cerca de mi computadora, pero la escala de frecuencia hace que sea muy impreciso para un sistema de escritorio moderno; Así que no lo use allí a menos que esté desnudo al metal y no haga tales cosas.
Aunque muchas implementaciones tienen la función de time
devolver el tiempo actual en segundos , no hay garantía de que cada implementación lo haga (por ejemplo, algunos pueden devolver milisegundos en lugar de segundos ). Como tal, una solución más portátil es usar la función difftime
.
difftime
está garantizado por el estándar C para devolver la diferencia en tiempo en segundos entre dos valores time_t
. Como tal, podemos escribir una función portátil de retardo de tiempo que se ejecutará en todas las implementaciones compatibles del estándar C.
#include <time.h>
void delay(double dly){
/* save start time */
const time_t start = time(NULL);
time_t current;
do{
/* get current time */
time(¤t);
/* break loop when the requested number of seconds have elapsed */
}while(difftime(current, start) < dly);
}
Una advertencia con las funciones de time
y difftime
es que el estándar C nunca especifica una granularidad. La mayoría de las implementaciones tienen una granularidad de un segundo . Si bien esto está bien para retrasos que duran varios segundos , nuestra función de demora puede esperar demasiado para que las demoras duren menos de un segundo .
Hay una alternativa C estándar portátil: la función de clock
.
La función de
clock
devuelve la mejor aproximación de la implementación al tiempo de procesador utilizado por el programa desde el comienzo de una era definida por la implementación relacionada solo con la invocación del programa. Para determinar el tiempo en segundos, el valor devuelto por la función delclock
debe dividir por el valor de la macroCLOCKS_PER_SEC
.
La solución de función de clock
es bastante similar a nuestra solución de función de time
:
#include <time.h>
void delay(double dly){
/* save start clock tick */
const clock_t start = clock();
clock_t current;
do{
/* get current clock tick */
current = clock();
/* break loop when the requested number of seconds have elapsed */
}while((double)(current-start)/CLOCKS_PER_SEC < dly);
}
En este caso, hay una advertencia similar a la de time
y time
difftime
: la granularidad de la función de clock
se deja a la implementación. Por ejemplo, las máquinas con valores de 32 bits para clock_t
con una resolución en microsegundos pueden terminar envolviendo el valor devuelto por el clock
después de 2147 segundos (aproximadamente 36 minutos).
Por lo tanto, considere utilizar la implementación de time
y time
difftime
de la función de retardo para retrasos que duran al menos un segundo , y la implementación del clock
para retrasos que duran menos de un segundo .
Una última palabra de advertencia: el clock
devuelve el tiempo del procesador en lugar del tiempo del calendario ; clock
puede no corresponder con el tiempo real transcurrido (por ejemplo, si el proceso duerme).
Compruebe la página man de sleep (3) o MSDN para dormir
Escribe este código:
void delay(int x)
{ int i=0,j=0;
for(i=0;i<x;i++){for(j=0;j<200000;j++){}}
}
int main()
{
int i,num;
while(1) {
delay(500);
printf("Host name");
printf("/n");}
}
Para retrasos de hasta un minuto, sleep()
es una buena opción.
Si algún día desea detenerse en retrasos de menos de un segundo, le recomendamos considerar poll()
con un tiempo de espera excedido.
Ambos son POSIX.
Prueba sleep(int number_of_seconds)
Si está seguro de que desea esperar y nunca ser interrumpido, utilice Sleep en POSIX o Sleep en Windows. En POSIX, el sueño lleva tiempo en segundos, por lo que si desea que el tiempo sea más corto existen variedades como usleep()
que usa microsegundos. Dormir en Windows lleva milisegundos, es raro que necesite una granularidad más fina que eso.
Es posible que desee esperar un período de tiempo pero desea permitir interrupciones, tal vez en el caso de una emergencia. el sueño puede ser interrumpido por señales, pero hay una mejor manera de hacerlo en este caso.
Por lo tanto, en la práctica descubrí que lo que haces es esperar un evento o una variable de condición con un tiempo de espera excedido.
En Windows, su llamada es WaitForSingleObject
. En POSIX, es pthread_cond_timedwait
.
En Windows también puede usar WaitForSingleObjectEx
y luego puede "interrumpir" su hilo con cualquier tarea en cola llamando a QueueUserAPC
. WaitForSingleObject (Ex) devolverá un código que determina por qué salió, por lo que sabrá cuándo devuelve un estado de "TIMEDOUT" que efectivamente expiró. Establece el evento que está esperando cuando desea que finalice.
Con pthread_cond_timedwait
puedes pthread_cond_timedwait
señal de la variable de condición. (Si hay varios hilos esperando en el mismo, tendrá que transmitir para activarlos todos). Cada vez que se repite, debe verificar la condición. Su hilo puede obtener la hora actual y ver si ha pasado o puede ver si se ha cumplido alguna condición para determinar qué hacer. Si tienes algún tipo de cola, puedes verificarlo. (Su hilo tendrá automáticamente un mutex bloqueado que solía esperar en la variable de condición, por lo que cuando comprueba la condición tiene acceso exclusivo).
simplemente puede llamar a la función de retraso (). Entonces, si desea retrasar el proceso en 3 segundos, llame al retraso (3000) ...
sleep(int)
funciona como un buen retraso. Por un minuto:
//Doing some stuff...
sleep(60); //Freeze for A minute
//Continue doing stuff...
En la norma C (C99), puede usar time()
para hacer esto, algo así como:
#include <time.h>
:
void waitFor (unsigned int secs) {
unsigned int retTime = time(0) + secs; // Get finishing time.
while (time(0) < retTime); // Loop until it arrives.
}
Por cierto, esto supone que time()
devuelve un valor de resolución de 1 segundo. No creo que eso sea obligatorio por el estándar, así que es posible que tengas que adaptarte.
Para aclarar, esta es la única forma que conozco de hacer esto con ISO C99 (y la pregunta está etiquetada con nada más que "C", lo que generalmente significa que las soluciones portátiles son deseables aunque, por supuesto, las soluciones específicas del proveedor todavía puede ser dado).
Por supuesto, si está en una plataforma que proporciona una forma más eficiente, úselo. Como han indicado varios comentarios, puede haber problemas específicos con un circuito cerrado como este, con respecto al uso de la CPU y la duración de la batería.
Cualquier sistema operativo decente de división de tiempo podría eliminar la prioridad dinámica de una tarea que utiliza continuamente su porción de tiempo completo, pero la potencia de la batería puede ser más problemática.
Sin embargo, C no especifica nada sobre los detalles del sistema operativo en un entorno alojado, y esta respuesta es solo para ISO C y ISO C (por lo que no se utilizan las llamadas de API de Win32, sleep
o Select ni nada de eso).
Y tenga en cuenta que el sleep
POSIX puede ser interrumpido por señales. Si vas por ese camino, debes hacer algo como:
int finishing = 0; // set finishing in signal handler
// if you want to really stop.
void sleepWrapper (unsigned int secs) {
unsigned int left = secs;
while ((left > 0) && (!finishing)) // Don''t continue if signal has
left = sleep (left); // indicated exit needed.
}
system("timeout /t 60"); // waits 60s. this is only for windows vista,7,8
system("ping -n 60 127.0.0.1 >nul"); // waits 60s. for all windows