web-dev-qa-db-fra.com

Comment utiliser la minuterie en C?

Quelle est la méthode pour utiliser une minuterie en C? Je dois attendre jusqu'à 500 ms pour un travail. Veuillez mentionner toute bonne façon de faire ce travail. J'ai utilisé sleep(3); Mais cette méthode ne fait aucun travail pendant cette durée. J'ai quelque chose qui va essayer jusqu'à ce moment-là pour obtenir une entrée.

8
user2332426

Vous pouvez utiliser une structure time_t Et une fonction clock() à partir de time.h .

Stockez l'heure de début dans une structure time_t En utilisant clock() et vérifiez le temps écoulé en comparant la différence entre l'heure stockée et l'heure actuelle.

8
Qutus

Voici une solution que j'ai utilisée (elle a besoin de #include <time.h>):

int msec = 0, trigger = 10; /* 10ms */
clock_t before = clock();

do {
  /*
   * Do something to busy the CPU just here while you drink a coffee
   * Be sure this code will not take more than `trigger` ms
   */

  clock_t difference = clock() - before;
  msec = difference * 1000 / CLOCKS_PER_SEC;
  iterations++;
} while ( msec < trigger );

printf("Time taken %d seconds %d milliseconds (%d iterations)\n",
  msec/1000, msec%1000, iterations);
10
David Guyon

Oui, vous avez besoin d'une boucle. Si vous avez déjà une boucle principale (la plupart des choses pilotées par les événements GUI le font), vous pouvez probablement y coller votre minuterie. Utilisation:

#include <time.h> 
time_t my_t, fire_t;

Ensuite (pour des durées supérieures à 1 seconde), initialisez votre minuterie en lisant l'heure actuelle:

my_t = time(NULL);

Ajoutez le nombre de secondes que votre temporisateur doit attendre et stockez-le dans fire_t. Un time_t est essentiellement un uint32_t, vous devrez peut-être le lancer.

À l'intérieur de votre boucle, faites-en une autre

my_t = time(NULL);

si (my_t> fire_t) alors considérez le minuteur déclenché et faites ce que vous voulez là-bas. Cela comprendra probablement la réinitialisation en faisant un autre fire_t = time (NULL) + seconds_to_wait pour la prochaine fois.

Un time_t est une méthode unix quelque peu archaïque de stockage du temps comme le nombre de secondes depuis minuit 1/1/1970 mais il présente de nombreux avantages. Pour des durées inférieures à 1 seconde, vous devez utiliser gettimeofday () (microsecondes) ou clock_gettime () (nanosecondes) et gérer un struct timeval ou struct timespec qui est un time_t et les microsecondes ou nanosecondes depuis cette marque de 1 seconde. Faire une minuterie fonctionne de la même manière, sauf lorsque vous ajoutez votre temps d'attente, vous devez vous rappeler de faire manuellement le report (dans le time_t) si la valeur de microsecondes ou de nanosecondes résultante dépasse 1 seconde. Oui, c'est désordonné. Voir man 2 time, man gettimeofday, man clock_gettime.

sleep (), usleep (), nanosleep () ont un avantage caché. Vous voyez cela comme une pause de votre programme, mais ce qu'ils font vraiment, c'est libérer le CPU pendant ce temps. L'interrogation répétée en lisant l'heure et en la comparant à l'heure terminée (y sommes-nous encore?) Brûlera beaucoup de cycles CPU, ce qui peut ralentir d'autres programmes en cours d'exécution sur la même machine (et utiliser plus d'électricité/batterie). Il vaut mieux dormir () la plupart du temps, puis commencer à vérifier l'heure.

Si vous essayez de dormir et de travailler en même temps, vous avez besoin de fils.

2
Alan Corey

Ces exemples peuvent vous aider

#include <stdio.h>
#include <time.h>
#include <stdlib.h>


/*
    Implementation simple timeout

    Input: count milliseconds as number

    Usage:
        setTimeout(1000) - timeout on 1 second
        setTimeout(10100) - timeout on 10 seconds and 100 milliseconds
 */
void setTimeout(int milliseconds)
{
    // If milliseconds is less or equal to 0
    // will be simple return from function without throw error
    if (milliseconds <= 0) {
        fprintf(stderr, "Count milliseconds for timeout is less or equal to 0\n");
        return;
    }

    // a current time of milliseconds
    int milliseconds_since = clock() * 1000 / CLOCKS_PER_SEC;

    // needed count milliseconds of return from this timeout
    int end = milliseconds_since + milliseconds;

    // wait while until needed time comes
    do {
        milliseconds_since = clock() * 1000 / CLOCKS_PER_SEC;
    } while (milliseconds_since <= end);
}


int main()
{

    // input from user for time of delay in seconds
    int delay;
    printf("Enter delay: ");
    scanf("%d", &delay);

    // counter downtime for run a rocket while the delay with more 0
    do {
        // erase the previous line and display remain of the delay
        printf("\033[ATime left for run rocket: %d\n", delay);

        // a timeout for display
        setTimeout(1000);

        // decrease the delay to 1
        delay--;

    } while (delay >= 0);

    // a string for display rocket
    char rocket[3] = "-->";

    // a string for display all trace of the rocket and the rocket itself
    char *rocket_trace = (char *) malloc(100 * sizeof(char));

    // display trace of the rocket from a start to the end
    int i;
    char passed_way[100] = "";
    for (i = 0; i <= 50; i++) {
        setTimeout(25);
        sprintf(rocket_trace, "%s%s", passed_way, rocket);
        passed_way[i] = ' ';
        printf("\033[A");
        printf("| %s\n", rocket_trace);
    }

    // erase a line and write a new line
    printf("\033[A");
    printf("\033[2K");
    puts("Good luck!");

    return 0;
}

Compiler le fichier, l'exécuter et le supprimer après (ma préférence)

$ gcc timeout.c -o timeout && ./timeout && rm timeout

Essayez de l'exécuter par vous-même pour voir le résultat.

Remarques:

Environnement de test

$ uname -a
Linux wlysenko-Aspire 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
$ gcc --version
gcc (Ubuntu 4.8.5-2ubuntu1~14.04.1) 4.8.5
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
2
PADYMKO