Le temps UNIX est mesuré sur votre ordinateur exécutant UNIX.
Cette réponse va vous demander de savoir ce que sont le temps universel coordonné (UTC), le temps atomique international (TAI) et le second SI. Les expliquer dépasse largement le cadre d'Unix et Linux Stack Exchange. Ce ne sont pas les échanges de pile de physique ou d'astronomie.
Le matériel
Votre ordinateur contient divers oscillateurs qui pilotent les horloges et les minuteries. Exactement ce qu'il a varie d'un ordinateur à l'autre en fonction de son architecture. Mais généralement et en termes très généraux:
- Il y a un temporisateur d'intervalle programmable (PIT) quelque part, qui peut être programmé pour compter un nombre donné d'oscillations et déclencher une interruption de l'unité centrale de traitement.
- Il y a un compteur de cycles sur le processeur central qui compte simplement 1 pour chaque cycle d'instructions exécuté.
La théorie du fonctionnement, en termes très larges
Le noyau du système d'exploitation utilise le PIT pour générer des ticks . Il configure le PIT en mode libre, comptant le bon nombre d'oscillations pendant un intervalle de temps, disons, d'un centième de seconde, générant une interruption, puis réinitialisant automatiquement le comptage pour recommencer. Il existe des variations à ce sujet, mais essentiellement cela provoque une interruption de tick à une fréquence fixe.
Dans le logiciel, le noyau incrémente un compteur à chaque tick. Il connaît la fréquence des ticks, car il a programmé le PIT en premier lieu. Il sait donc combien de ticks composent une seconde. Il peut l'utiliser pour savoir quand incrémenter un compteur qui compte des secondes. Ce dernier est l'idée du noyau de "UNIX Time". En effet, il compte simplement à la hausse à raison d'un par seconde SI s'il est laissé à ses propres appareils.
Quatre choses compliquent cela, que je vais présenter en termes très généraux.
Le matériel n'est pas parfait. Un PIT dont la fiche technique indique qu'il a une fréquence d'oscillateur de N Hertz pourrait plutôt avoir une fréquence de (disons) N .00002 Hertz, avec les conséquences évidentes.
Ce schéma interagit très mal avec la gestion de l'alimentation, car le processeur se réveille des centaines de fois par seconde pour faire un peu plus qu'incrémenter un nombre dans une variable. Ainsi, certains systèmes d'exploitation ont ce que l'on appelle des conceptions «sans tique». Au lieu de faire en sorte que le PIT envoie une interruption pour chaque tick, le noyau calcule (à partir de l'ordonnanceur de bas niveau) combien de ticks vont se passer sans quanta de thread, et programme le PIT pour compter autant de ticks dans le avant d'émettre une interruption de tick. Il sait qu'il doit alors enregistrer le passage de N ticks à la prochaine interruption de tick, au lieu de 1 tick.
Le logiciel d'application a la capacité de changer l'heure actuelle du noyau. Il peut augmenter la valeur ou faire pivoter la valeur. L'orientation consiste à ajuster le nombre de ticks qui doivent passer pour incrémenter le compteur de secondes. Le compteur de secondes ne compte donc pas nécessairement au rythme de un par seconde SI de toute façon , même en supposant des oscillateurs parfaits. Le pas implique simplement d'écrire un nouveau nombre dans le compteur de secondes, ce qui ne se produit généralement pas avant 1 seconde SI depuis la dernière seconde.
Les noyaux modernes comptent non seulement les secondes, mais aussi les nanosecondes. Mais il est ridicule et souvent irréalisable d'avoir une interruption de tique une fois par nanoseconde. C'est là que des choses comme le compteur de cycles entrent en jeu. Le noyau se souvient de la valeur du compteur de cycles à chaque seconde (ou à chaque tick) et peut calculer, à partir de la valeur actuelle du compteur lorsque quelque chose veut connaître le temps en nanosecondes, combien de nanosecondes doivent s'être écoulées depuis la dernière seconde (ou cocher). Encore une fois, cependant, la gestion de l'alimentation et de la chaleur fait des ravages car la fréquence du cycle d'instruction peut changer, de sorte que les noyaux font des choses comme s'appuyer sur du matériel supplémentaire comme (par exemple) un temporisateur d'événements de haute précision (HPET).
Le langage C et POSIX
La bibliothèque standard de la langue C décrit le temps en termes d'un type opaque, time_t
un type de structure tm
avec différents domaines spécifiés, ainsi que diverses fonctions de bibliothèque comme time()
, mktime()
et localtime()
.
En bref: le langage C lui-même garantit simplement qu'il time_t
s'agit d'un des types de données numériques disponibles et que le seul moyen fiable de calculer les différences de temps est la difftime()
fonction. C'est le standard POSIX qui fournit les garanties les plus strictes qui time_t
est en fait l'un des types entiers et qu'il compte en secondes depuis l'Époque . C'est également la norme POSIX qui spécifie le timespec
type de structure.
La time()
fonction est parfois décrite comme un appel système. En fait, cela n'a pas été l'appel système sous-jacent sur de nombreux systèmes depuis assez longtemps, de nos jours. Sur FreeBSD, par exemple, l'appel système sous-jacent est clock_gettime()
, qui dispose de différentes "horloges" qui mesurent en secondes ou en secondes + nanosecondes de différentes manières. C'est cet appel système par lequel le logiciel d'application lit l'heure UNIX à partir du noyau. (Un clock_settime()
appel système correspondant leur permet de le déplacer et un adjtime()
appel système leur permet de le faire pivoter.)
Beaucoup de gens agitent la norme POSIX avec des affirmations très précises et précises sur ce qu'elle prescrit. Ces personnes n'ont, le plus souvent, pas réellement lu la norme POSIX. Comme l'explique sa justification, l'idée de compter "secondes depuis l'époque", qui est la phrase que la norme utilise, ne spécifie pas intentionnellement que les secondes POSIX sont de la même longueur que les secondes SI, ni que le résultat gmtime()
est "nécessairement UTC, malgré son apparence ". La norme POSIX est intentionnellementsuffisamment lâche pour qu'il permette (par exemple) un système UNIX où l'administrateur va et corrige manuellement les ajustements de la seconde intercalaire en remettant à zéro l'horloge la semaine après qu'ils se produisent. En effet, la justification souligne qu'elle est intentionnellement assez lâche pour s'adapter aux systèmes où l'horloge a été délibérément réglée à une heure autre que l'heure UTC actuelle.
UTC et TAI
L'interprétation de UNIX Time obtenue à partir du noyau dépend des routines de bibliothèque exécutées dans les applications. POSIX spécifie une identité entre le temps du noyau et un "temps décomposé" dans a struct tm
. Mais, comme Daniel J. Bernstein l'a souligné une fois, l'édition 1997 de la norme s'est trompée de façon embarrassante sur cette identité, brouillant la règle de l'année bissextile du calendrier grégorien (quelque chose que les écoliers apprennent) de sorte que le calcul était erroné à partir de l'année 2100. "Plus honoré dans la brèche que l'observance" est une phrase qui me vient à l'esprit.
Et c'est effectivement le cas. De nos jours, plusieurs systèmes basent cette interprétation sur des routines de bibliothèque écrites par Arthur David Olson, qui consultent la fameuse "base de données de fuseau horaire Olson", généralement encodée dans des fichiers de base de données sous /usr/share/zoneinfo/
. Le système Olson avait deux modes:
- Les "secondes depuis l'époque" du noyau sont considérées comme comptant les secondes UTC depuis le 1970-01-01 00:00:00 UTC, à l'exception des secondes intercalaires. Cela utilise l'
posix/
ensemble des fichiers de base de données de fuseau horaire Olson. Tous les jours ont 86400 secondes de noyau et il n'y a jamais 61 secondes dans une minute, mais elles ne sont pas toujours de la longueur d'une seconde SI et l'horloge du noyau doit pivoter ou avancer lorsque des secondes intercalaires se produisent.
- Les "secondes depuis l'époque" du noyau sont considérées comme comptant les secondes TAI depuis le 1970-01-01 00:00:10 TAI. Cela utilise l'
right/
ensemble des fichiers de base de données de fuseau horaire Olson. Les secondes du noyau durent 1 seconde SI et l'horloge du noyau n'a jamais besoin de pivoter ou de se déplacer pour s'adapter aux secondes intercalaires, mais les temps décomposés peuvent avoir des valeurs telles que 23:59:60 et les jours ne sont pas toujours longs de 86400 secondes.
M. Bernstein a écrit plusieurs outils, y compris son daemontools
jeu d'outils, qui nécessitaient right/
car ils ont simplement ajouté 10 time_t
pour obtenir des secondes TAI depuis 1970-01-01 00:00:00 TAI. Il a documenté cela dans la page de manuel.
Cette exigence a été (peut-être inconsciemment) héritée par des ensembles d'outils tels que daemontools-encore
et runit
et par Felix von Leitner.libowfat
. Utilisez Bernsteinmultilog
, Guentermultilog
ou Papesvlogd
avec une posix/
configuration Olson , par exemple, et tous les horodatages TAI64N auront (au moment de la rédaction de ce document) 26 secondes de retard sur le nombre réel de secondes TAI depuis 1970-01-01 00:00:10 TAI.
Laurent Bercot et moi avons abordé cette question en s6 et nosh, bien que nous ayons adopté des approches différentes. M. Bercot tai_from_sysclock()
s'appuie sur un indicateur de compilation. les outils nosh qui traitent dans TAI64N regardent les variables d'environnement TZ
et TZDIR
pour détecter automatiquement posix/
et right/
si elles le peuvent.
Fait intéressant, les documents time2posix()
et posix2time()
fonctions FreeBSD qui permettent l'équivalent du right/
mode Olson avec time_t
comme secondes TAI. Cependant, ils ne sont apparemment pas activés.
Encore une fois…
Le temps UNIX est mesuré sur votre ordinateur exécutant UNIX, par des oscillateurs contenus dans le matériel de votre ordinateur. Il n'utilise pas SI secondes; ce n'est pas UTC même s'il peut lui ressembler superficiellement; et cela permet intentionnellement à votre horloge de se tromper.
Lectures complémentaires