web-dev-qa-db-fra.com

Obtenir un horodatage en C en microsecondes?

Comment obtenir un horodatage en microsecondes en C?

J'essaie de faire:

struct timeval tv;
gettimeofday(&tv,NULL);
return tv.tv_usec;

Mais ceci retourne une valeur insensée que si j'ai deux horodatages, le second peut être plus petit ou plus grand que le premier (le second devrait toujours être plus grand). Serait-il possible de convertir le nombre entier magique renvoyé par gettimeofday en un nombre normal avec lequel on peut réellement travailler?

34
Kristina Brooks

Vous devez également ajouter dans les secondes:

unsigned long time_in_micros = 1000000 * tv.tv_sec + tv.tv_usec;

Notez que cela ne durera que pendant environ 232/dix6 = Environ 4295 secondes, soit environ 71 minutes (sur un système 32 bits typique).

43
unwind

Vous avez deux choix pour obtenir un horodatage en microsecondes. Le premier (et le meilleur) choix consiste à utiliser directement le type timeval:

struct timeval GetTimeStamp() {
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv;
}

Le second choix, et pour moi moins souhaitable, est de construire un uint64_t sur une timeval:

uint64_t GetTimeStamp() {
    struct timeval tv;
    gettimeofday(&tv,NULL);
    return tv.tv_sec*(uint64_t)1000000+tv.tv_usec;
}
18
Robᵩ

struct timeval contient deux composants, le second et la microseconde. Un horodatage avec une précision en microsecondes est représenté en secondes depuis l'époque stockée dans le champ tv_sec et la fraction de microsecondes dans tv_usec. Ainsi, vous ne pouvez pas ignorer tv_sec et attendre des résultats probants.

Si vous utilisez Linux ou * BSD, vous pouvez utiliser timersub () pour soustraire deux valeurs de structure timeval, qui peuvent correspondre à vos besoins.

8
janneb

timespec_get de C11 renvoie jusqu'à nanosecondes, arrondi à la résolution de l'implémentation.

#include <time.h>
struct timespec ts;
timespec_get(&ts, TIME_UTC);
struct timespec {
    time_t   tv_sec;        /* seconds */
    long     tv_nsec;       /* nanoseconds */
};

Plus de détails ici: https://stackoverflow.com/a/36095407/895245

Mais cela retourne une valeur absurde que si j'ai deux horodatages, le la seconde peut être plus petite ou plus grande que le premier (le second devrait toujours être plus grand).

Qu'est ce qui te fait penser ça? La valeur est probablement OK. C’est la même chose que pour les secondes et les minutes - lorsque vous mesurez le temps en minutes et en secondes, le nombre de secondes revient à zéro quand il atteint soixante.

Pour convertir la valeur renvoyée en un nombre «linéaire», vous pouvez multiplier le nombre de secondes et ajouter les microsecondes. Mais si je compte correctement, une année équivaut à environ 1e6 * 60 * 60 * 24 * 360 μsec et cela signifie que vous aurez besoin de plus de 32 bits pour stocker le résultat:

$ Perl -E '$_=1e6*60*60*24*360; say int log($_)/log(2)'
44

C’est probablement l’une des raisons pour lesquelles la valeur renvoyée d’origine a été scindée en deux parties.

2
zoul

utilisez un long long non signé (c’est-à-dire une unité de 64 bits) pour représenter l’heure du système

typedef unsigned long long u64;

u64 u64useconds;
struct timeval tv;

gettimeofday(&tv,NULL);
u64useconds = (1000000*tv.tv_sec) + tv.tv_usec;
0
user6269400

Nous devons d’abord connaître la plage de microsecondes, à savoir 000 000 à 999_999 (1 000 microsecondes est égal à 1 seconde). tv.tv_usec renverra une valeur comprise entre 0 et 999999, pas 000000 à 999999 . Ainsi, si vous l'utilisez avec des secondes, vous obtiendrez peut-être 2,1 secondes au lieu de 2,000001 secondes. C'est mieux si vous insérez 

if(tv.tv_usec<10)
{
 printf("00000");
} 
else if(tv.tv_usec<100&&tv.tv_usec>9)// i.e. 2digits
{
 printf("0000");
}

etc...

0
Osaid