« Temps à la milliseconde en C » : différence entre les versions

De knowledge
Aller à la navigation Aller à la recherche
(Page créée avec « Autant en java ou en python gérer le temps en millisecondes est standard. En C c'est pas si simple. Certes en C dans l'environnement Arduino c'est facile, un simple milis() donne le nombre de millisecondes depuis le boot en C sous linux c'est plus subtil. En C standard on a une fonction dans <code><time.h></code> qui fait le travail (et encore plus) : <code>clock_gettime</code> dont la page de man est donnée : https://man7.org/linux/man-pages/man3/clock_... »)
 
mAucun résumé des modifications
 
Ligne 71 : Ligne 71 :
Timestamp 1764455240.930000
Timestamp 1764455240.930000
Timestamp 1764455241.932000
Timestamp 1764455241.932000
</syntaxhighlight>En moyenne on une mesure toutes les 1.004867 secondes. Si on considère que le sleep 1 est précis le reste de la boucle prends 4,8 ms. C'est pas rapide la bash!
</syntaxhighlight>Avec mon PC et WSL, en moyenne on une mesure toutes les 1.004867 secondes. Si on considère que le sleep 1 est précis le reste de la boucle prends 4,8 ms. C'est pas rapide la bash!
 
Avec mon PI4 c'est plutôt 1.008867 secondes soit presque 9ms !
 
Avec ma VM chez Gandi c'est 1.014571 soit près de 15ms !
 
Vive l'auto-hébergement sur Raspberry PI.

Version actuelle datée du 29 novembre 2025 à 22:42

Autant en java ou en python gérer le temps en millisecondes est standard. En C c'est pas si simple.

Certes en C dans l'environnement Arduino c'est facile, un simple milis() donne le nombre de millisecondes depuis le boot en C sous linux c'est plus subtil.

En C standard on a une fonction dans <time.h> qui fait le travail (et encore plus) : clock_gettime dont la page de man est donnée : https://man7.org/linux/man-pages/man3/clock_gettime.3.html

clock_gettime

Cette fonction prends deux paramètres.

  • Une valeur constante donnant la façon de mesurer le temps : Dans notre cas CLOCK_REALTIME est parfait. Ce n'est pas le plus rapide mais le plus précis.
  • Un pointeur vers une structure struct timespec
/*The res and tp arguments are timespec structures, as specified in
  <time.h>:*/

struct timespec {
    time_t   tv_sec;        /* Timestamp from EPOCH in seconds. like time()*/
    long     tv_nsec;       /* nanoseconds */
};

Pour avoir une fonction qui donne le timestamp en millisecondes (le milis() d'Arduino)

#include <time.h>

long long millis(void) {
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    return ((long long)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
}

Logiquement il faut multiplier les secondes par 1000 pour avoir des millisecondes et diviser par 1000 les nanosecondes pour avoir des microsecondes puis encore par 1000 pour des millisecondes.

Exemple

/* File gettime.c*/

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

long long millis(void) {
    struct timespec ts;
    clock_gettime(CLOCK_REALTIME, &ts);
    return ((long long)ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
}

int main (){
    printf ("Timestamp %f\n",millis()/1000.0);
}

Imprime l'heure en secondes décimales (à la Python). On compile:

cc -o gettime gettime.c

et on teste avec par exemple:

while [ 1 ]
do
  ./gettime
  sleep 1
done

Qui me donne

Timestamp 1764455226.859000
Timestamp 1764455227.864000
Timestamp 1764455228.872000
Timestamp 1764455229.882000
Timestamp 1764455230.888000
Timestamp 1764455231.891000
Timestamp 1764455232.895000
Timestamp 1764455233.899000
Timestamp 1764455234.907000
Timestamp 1764455235.913000
Timestamp 1764455236.917000
Timestamp 1764455237.920000
Timestamp 1764455238.923000
Timestamp 1764455239.927000
Timestamp 1764455240.930000
Timestamp 1764455241.932000

Avec mon PC et WSL, en moyenne on une mesure toutes les 1.004867 secondes. Si on considère que le sleep 1 est précis le reste de la boucle prends 4,8 ms. C'est pas rapide la bash!

Avec mon PI4 c'est plutôt 1.008867 secondes soit presque 9ms !

Avec ma VM chez Gandi c'est 1.014571 soit près de 15ms !

Vive l'auto-hébergement sur Raspberry PI.