2010-10-14 28 views
23

No sé exactamente cómo redactar una búsqueda para este .. así que no he tenido un poco de suerte encontrar nada ..: Saplicar retardo de tiempo en c

que necesito para aplicar un retardo de tiempo en C

por ejemplo, quiero hacer algunas cosas, luego esperar, decir 1 minuto, luego continuar haciendo las cosas.

¿Eso tenía sentido? ¿Puede alguien ayudarme?

+3

Qué plataforma y sistema operativo? – detly

Respuesta

29

En C estándar (C99), puede utilizar time() a ello, 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 time() devuelve un 1 segundo valor de resolución . No creo que eso sea obligatorio por el estándar, así que es posible que tengas que adaptarte.


Con el fin de aclarar, esta es la única forma en que estoy consciente de hacer esto con la norma ISO C99 (y la cuestión se etiqueta con nada más que "C", que por lo general significa soluciones portátiles son deseables aunque, por supuesto, aún se pueden dar soluciones específicas del proveedor).

Por supuesto, si se encuentra en una plataforma que proporciona una forma más eficiente, úselo usando . 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 decente de división de tiempo podría descartar la prioridad dinámica de una tarea que utiliza continuamente su porción de tiempo completo, pero la energía de la batería puede ser más problemática.

Sin embargo C especifica nada acerca de los detalles del sistema operativo en un entorno alojado, y esta respuesta es para C ISO e ISO C sola (por lo que no uso de sleep, select, Win32 llamadas a la API o algo por el estilo).

Y tenga en cuenta que POSIX sleep puede ser interrumpido por señales.Si está va a ir por ese camino, es necesario 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. 
} 
+2

¿qué hay de la carga de la CPU? – SysAdmin

+1

Sí, habrá una carga de CPU, pero cualquier SO decente (suponiendo que se realice una multitarea de forma preventiva) lo detectará y descartará la prioridad dinámica en consecuencia. Y, si no lo es, la carga de la CPU no importa (si se trata de una tarea múltiple, es posible que desee examinar una función 'yield'). La razón por la que publiqué esto es porque no hay una forma portátil ISO-C para hacerlo y la pregunta está etiquetada solo como "C" ("sleep", aunque es útil, no es "estándar"). – paxdiablo

+2

@paxdiablo: No, de hecho no ... La frecuencia de reloj de una de las CPU aumentará al 100% por ciento. Y la carga de la CPU es importante, especialmente si está en una computadora portátil, cuando la CPU está maximizada genera calor y el calor acorta la vida útil de la computadora. En un viejo estacionario que probablemente no importe, así es como lo maneja Windows (un bucle sin fin que no hace nada cuando no hay nada que hacer). Supongo que hoy en día los SO utilizan tecnologías avanzadas de ahorro de energía, pero sé que el kernel de Linux emitió una instrucción hlt, lo mismo hice cuando tenía 12 años. – Frank

0

Trate sleep(int number_of_seconds)

1

sleep(int) funciona como un buen retraso. Durante un minuto:

//Doing some stuff... 
sleep(60); //Freeze for A minute 
//Continue doing stuff... 
14

Aquí es cómo usted 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 puede hacerlo en un microordenador procesador/w/o 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 ser afinados, los funcionó bastante cerca de mi equipo, pero la escala de frecuencias t hing lo hace 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.

+0

+1 para compensar un downvote inmerecido en mi humilde opinión. Por otro lado, está asumiendo claramente un sistema operativo con llamadas al sistema útiles y la pregunta real solo menciona el estándar C que, como señala Pax, carece de cualquier tipo de llamada de retraso. Una gran cantidad de código C se ejecuta en plataformas sin sistemas operativos. Aunque a menudo es bueno crear un mecanismo similar a 'sleep()' en dichas plataformas, no es requerido por ninguno de los estándares de C. – RBerteig

+0

Estaba pensando en escribir sobre cómo hacerlo en microprocesadores sin un sistema operativo, pero no lo sentí. No es realmente mi campo. – Frank

+1

@Frank, incluso sin sistema operativo, a menudo tiene un contador implementado en hardware que cuenta los ciclos de algún reloj. De modo que una forma es leer ese contador, predecir un valor futuro y girar en un bucle hasta que el contador alcance el valor. Eso funciona para esperar lo suficientemente corto como para que el contador no se envuelva más de una vez mientras espera. En CPUs pequeñas, a veces tiene que recurrir a bucles ajustados a mano donde sabe exactamente cuántos ciclos se consumen por iteración. Siempre hay una manera, pero puede no ser bonita. – RBerteig

0

puede simplemente llamar a la función de retraso(). Por lo tanto, si desea retrasar el proceso en 3 segundos, llame al retraso (3000) ...

3

Para retrasos de hasta un minuto, sleep() es una buena opción.

Si algún día desea pausar en retrasos de menos de un segundo, es posible que desee considerar poll() con un tiempo de espera excedido.

Ambos son POSIX.

0

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 hace 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 realmente "interrumpir" el hilo con cualquier tarea en cola llamando al 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 puede transmitir 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).

5

aunque muchas implementaciones tienen la función time devuelve la hora actual en segundos , no hay ninguna garantía de que cada aplicación lo hará (por ejemplo, algunos pueden volver milisegundos en lugar de segundos).Como tal, una solución más portátil es usar la función difftime.

difftime está garantizada por la norma C para devolver la diferencia en el tiempo en segundo entre dos time_t valores. 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(&current); 

     /* break loop when the requested number of seconds have elapsed */ 
    }while(difftime(current, start) < dly); 
} 

Una advertencia con los time y difftime funciones es que la C estándar nunca se 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 retardo puede esperar demasiado tiempo para retrasos que duran en un segundo.

Hay una alternativa estándar portátil C: la función clock.

La función clock devuelve mejor aproximación de la aplicación a tiempo de procesador utilizado por el programa desde el comienzo de una era definida por la implementación se refiere únicamente a la invocación del programa. Para determinar el tiempo en segundos, el valor devuelto por la función clock se debe dividir por el valor de la macro CLOCKS_PER_SEC.

La solución función clock es bastante similar a nuestra solución time función:

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

Hay una advertencia en este caso similar al de time y difftime: la granularidad de la función clock se deja 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 clock después de 2147 segundos (aproximadamente 36 minutos).

Como tal, puede utilizar el time y difftime implementación de la función de retardo de los retrasos que duran al menos un segundo y la implementación clock de los retrasos que duran menos de un segundo .

Una última palabra de precaución: clock tiempo vuelve procesador tiempo en lugar de calendario; clock puede no corresponder con el tiempo real transcurrido (por ejemplo, si el proceso duerme).

-1
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 
+0

¿Sabes que C no es la abreviatura de CMD, ¿verdad? – robbie0630

-1

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

} 
+1

Agregue algunas explicaciones con la respuesta de cómo esta respuesta ayuda OP en la fijación de la edición actual –

+0

compilar esto con la optimización activada eliminará toda la función de retardo – Tommylee2k

Cuestiones relacionadas