Comment empêcher le temps de revenir en arrière sous Linux?

Voici un petit test que j’ai écrit pour vérifier que le temps ne marche effectivement que sous Linux.

#include  #include  bool timeGoesForwardTest2() { timeval tv1, tv2; double startTime = getTimeSeconds(); // my function while ( getTimeSeconds() - startTime tv1.tv_usec || tv2.tv_sec-1 == tv1.tv_sec ) ) { printf( "tv1: %d %d\n", int( tv1.tv_sec ), int( tv1.tv_usec ) ); printf( "tv2: %d %d\n", int( tv2.tv_sec ), int( tv2.tv_usec ) ); return false; } } return true; } 

Le test échoue avec le résultat.

  tv1: 1296011067 632550 tv2: 1296011067 632549 

humm ….

Pourquoi cela arrive-t-il?

Voici ma configuration:

 Linux version 2.6.35-22-generic (buildd@rothera) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu4) ) #33-Ubuntu SMP Sun Sep 19 20:34:50 UTC 2010 (Ubuntu 2.6.35-22.33-generic 2.6.35.4) ... running inside VirtualBox 3.2.12, in Windows 7. 

Il y a un problème ouvert sur le Bug Tracker de VirtualBox . Ils sont liés à un article de blog indiquant pourquoi vous ne devez pas utiliser gettimeofday () pour mesurer le temps écoulé:

Le moyen le plus portable de mesurer correctement le temps semble être clock_gettime (CLOCK_MONOTONIC, …)

gettimeofday() n’est pas garanti pour être monotone. Utilisez clock_gettime(CLOCK_MONOTONIC) si vous avez besoin de cette garantie.

Les timers de machines sur la plupart des machines ont une précision d’environ 15 usec (même pour le code natif). Le temps passé «en arrière» est étrange, mais vous ne pouvez vraiment pas compter sur ce niveau (1 usec). (Notez également: il existe une différence entre précision et précision; la précision de la plupart des timers est pire que sa précision). L’utilisation d’une machine virtuelle peut également aggraver la situation.

Mise à jour: Typo

Ce n’est pas que ça marche à l’envers. Il serait préférable de dire qu’il ne rapporte pas l’heure correcte. En effet, les ordinateurs, sans l’aide d’un sous-système de synchronisation dédié, ne sont tout simplement pas capables de signaler l’heure de manière très précise en intervalles d’une milliseconde.

La précision variera en fonction du matériel, du système d’exploitation et même de l’alimentation. Voici un article pour les débutants . Un peu vieux mais communique bien l’idée.

Le temps ne devrait pas revenir en arrière sur du matériel réel; sur une VM, votre kilométrage peut varier.

Dans tous les cas, votre application ne devrait probablement pas supposer que le temps ne recule pas très légèrement (pensez, peut-être 1 seconde).

Oui, le paramètre clock_gettime est bon, mais même celui-ci pourrait fonctionner en arrière en cas de matériel défectueux (ou d’une machine virtuelle, comme dans votre exemple).

J’ai vu un bogue de matériel faire reculer le temps (bien que très occasionnellement), il était une cause de problèmes très particuliers.

En particulier, tout ce qui implique de comparer les horodatages des fichiers ne fonctionnera pas correctement avec le temps.