Synopsis: Quand j'étudiais le traitement de l'argument de clock_gettime (2)
dans chaque langue, j'ai trouvé une phrase tellement étrange. En raison de telles circonstances, il n'y a pas de description liée à Windows. Je peux l'ajouter plus tard.
clock_gettime
clock_gettime (2)
est une API pour l'acquisition du temps normalisée par la spécification Unix unique v2. Pour clock_gettime (2)
, la sémantique et la précision de l'acquisition du temps changent en fonction de la constante passée à clock_id
.
Pour citer un exemple d'un homme Linux
- CLOCK_REALTIME
Un temps unique à l'échelle du système qui mesure le temps réel. Des privilèges appropriés sont requis pour régler cette horloge. Cette horloge est un changement discontinu de l'heure du système(Par exemple, si l'administrateur système modifie manuellement l'heure système.)Il est affecté par les ajustements progressifs effectués par adjtime et NTP.
CLOCK_REALTIME_COARSE (Linux 2.6.32 ou plus tard;Spécifique à Linux)
HORLOGE rapide mais de faible précision_TEMPS RÉEL. Il est recommandé de l'utiliser lorsque la vitesse est très nécessaire et qu'un horodatage de haute précision n'est pas nécessaire.
CLOCK_MONOTONIC
Une horloge qui ne peut pas être réglée et qui est exprimée comme un temps d'augmentation monotone à partir d'un certain point de départ.(Il n'est pas spécifié quand l'heure de début sera).. Cette horloge a des changements discontinus dans l'heure du système(Par exemple, si l'administrateur système modifie manuellement l'heure système.)Non affecté par, mais adjtime(3)Et sont affectés par les ajustements progressifs apportés par NTP.
CLOCK_MONOTONIC_COARSE (Linux 2.6.32 ou plus tard;Spécifique à Linux)
HORLOGE rapide mais de faible précision_MONOTONIQUE. Il est recommandé de l'utiliser lorsque la vitesse est très nécessaire et qu'un horodatage de haute précision n'est pas nécessaire.
CLOCK_MONOTONIC_RAW (Linux 2.6.28 ou plus tard;Spécifique à Linux)
CLOCK_Similaire à MONOTONIC, mais avec des ajustements NTP et une(3)Fournit un accès matériel au temps brut, non affecté par les ajustements progressifs effectués par.
CLOCK_BOOTTIME (Linux 2.6.39 ou plus tard;Spécifique à Linux)
CLOCK_Identique à MONOTONIC, sauf qu'il inclut également le temps pendant lequel le système est suspendu. Avec lui, l'application peut également gérer les états suspendus"monotonic"L'horloge peut être obtenue. De plus, CLOCK_Il n'est pas nécessaire d'effectuer un traitement compliqué en TEMPS RÉEL. L'HORLOGE_En TEMPS RÉEL, settimeofday(2)En effet, si vous modifiez l'heure en utilisant, l'heure changera de manière discontinue.
une. Cette constante varie en fonction du système d'exploitation. D'autres, comme sierra, ont ajouté une API spéciale appelée clock_gettime_nsec_np
.
Dans ce blog, la partie citée de l'implémentation a été utile. http://d.hatena.ne.jp/yohei-a/20140913/1410628229
Ruby
Process.clock_gettime
Ruby fournit une API qui appelle directement clock_gettime (2)
. Spécifiez clock_id
dans l'argument de Process.clock_gettime.
Selon process.c, les constantes suivantes peuvent être spécifiées. Il décrit également dans quelle version il a été correctement ajouté, ce qui est très merveilleux. Il n'y avait aucune spécification pour CLOCK_HIGHRES sur Solaris. Dragonfly BSD devrait également pouvoir utiliser les mêmes options que FreeBSD, du moins dans la dernière version, mais cela n'a pas été mentionné.
* [CLOCK_REALTIME] SUSv2 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 2.1, macOS 10.12
* [CLOCK_MONOTONIC] SUSv3 to 4, Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4, macOS 10.12
* [CLOCK_PROCESS_CPUTIME_ID] SUSv3 to 4, Linux 2.5.63, OpenBSD 5.4, macOS 10.12
* [CLOCK_THREAD_CPUTIME_ID] SUSv3 to 4, Linux 2.5.63, FreeBSD 7.1, OpenBSD 5.4, macOS 10.12
* [CLOCK_VIRTUAL] FreeBSD 3.0, OpenBSD 2.1
* [CLOCK_PROF] FreeBSD 3.0, OpenBSD 2.1
* [CLOCK_REALTIME_FAST] FreeBSD 8.1
* [CLOCK_REALTIME_PRECISE] FreeBSD 8.1
* [CLOCK_REALTIME_COARSE] Linux 2.6.32
* [CLOCK_REALTIME_ALARM] Linux 3.0
* [CLOCK_MONOTONIC_FAST] FreeBSD 8.1
* [CLOCK_MONOTONIC_PRECISE] FreeBSD 8.1
* [CLOCK_MONOTONIC_COARSE] Linux 2.6.32
* [CLOCK_MONOTONIC_RAW] Linux 2.6.28, macOS 10.12
* [CLOCK_MONOTONIC_RAW_APPROX] macOS 10.12
* [CLOCK_BOOTTIME] Linux 2.6.39
* [CLOCK_BOOTTIME_ALARM] Linux 3.0
* [CLOCK_UPTIME] FreeBSD 7.0, OpenBSD 5.5
* [CLOCK_UPTIME_FAST] FreeBSD 8.1
* [CLOCK_UPTIME_RAW] macOS 10.12
* [CLOCK_UPTIME_RAW_APPROX] macOS 10.12
* [CLOCK_UPTIME_PRECISE] FreeBSD 8.1
* [CLOCK_SECOND] FreeBSD 8.1
Time.now
L'heure actuelle la plus couramment utilisée, appelée «Time.now» ou «Time # initialize», est fixée à «CLOCK_REALTIME» si clock_gettime est défini. Sinon, utilisez gettimeofday (macOS, etc.).
Bien qu'il ne soit pas écrit dans Documentation, si clock_gettime / gettimeofday échoue en interne, rb_sys_fail Faites une exception avec
.
time.clock_gettime
Depuis la version 3.3, Python peut appeler directement clock_gettime (2)
avec time.clock_gettime (clock_id)
comme Ruby. Cependant, ce qui peut être passé à clock_id est et documenté, et apparemment des constantes telles que CLOCK_MONOTONIC_COARSE
ne peuvent pas être passées (à partir de 3.6.0). En premier lieu, Python ne semble pas fournir une API qui utilise CLOCK_MONOTONIC_COARSE
en interne ou la transmet de l'extérieur.
En regardant pytime.c, la fonction pymonotonique est fixée à CLOCK_MONOTONIC
, et la fonction pygettimeofday est utilisée pour corriger CLOCK_REALTIME
. Dans pymonotonic, mach_absolute_time
est passé pour macOS et CLOCK_HIGHRES
est passé pour Solaris.
time.time
Le plus couramment utilisé time.time ()
appelle en interne la fonction pygetimeofday
, ce qui équivaut à time.clock_gettime (CLOCK_REALTIME)
. Comme Time.now dans Ruby, gettimeofday (2) est utilisé comme destination de secours.
Si l'appel système échoue, il renvoie NULL en interne, mais je ne suis pas sûr.
pep418
Il s'agit de la proposition PEP basée sur l'horloge nouvellement ajoutée au module de temps dans Python 3.3 https://www.python.org/dev/peps/pep-0418/
Perl5
Est-il attaché au corps principal? Le module Time :: HiRes qui est en train de faire semble être le de facto.
clock_gettime
Vous pouvez passer CLOCK_MONOTONIC
ou CLOCK_REALTIME
à clock_gettime
. Comme Ruby et Python, clock_gettime ne grandit pas s'il n'est pas défini du côté OS, il n'y a donc pas de mécanisme pour revenir à gettimofday (2). Pour le moment, il ne prend pas en charge l'API nouvellement créée dans le dernier macOS Sierra, mais «CLOCK_MONOTONIC_FAST» de FreeBSD, etc. sont définis comme des constantes.
time
La fonction time appelle en interne gettimeofday (2). Il semble retourner -1.0 si l'appel à gettimeofday (2) échoue. Quand je me suis demandé ce que cela signifiait, je me suis demandé si l'état d'échec de l'appel système était exprimé sous forme de flottant. Puisqu'il n'y a pas de type de somme directe, de type de produit direct ou d'exception en Perl, il est probablement préférable d'exprimer les valeurs de retour de manière mixte.
C'est devenu ennuyeux, donc c'est devenu désordonné.
C++
Regardez std :: chrono (libstdc ++ - v3 / src / c ++ 11 / chrono.cc) dans STL.
std::chrono::system_clock::now
CLOCK_REALTIME
si vous avez clock_gettime (2)std::chrono::steady_clock::now
CLOCK_MONOTONIC
si vous avez clock_gettime (2)Il est devenu.
Go
De nombreuses plates-formes (Linux, FreeBSD, OpenBSD) utilisent CLOCK_REALTIME
pour implémenter maintenant
et CLOCK_MONOTONIC
pour implémenter nanotime
pour chaque architecture. Pour NetBSD et Solaris, CLOCK_REALTIME
est également utilisé pour implémenter nanotime, mais je ne suis pas sûr. Je ne suis pas sûr de Plan9.
La situation est compliquée sous macOS, probablement parce qu'il s'agit d'un binaire lié statiquement. Mais je ne suis pas sur. Conservez uniquement l'URL référencée. https://opensource.apple.com/source/xnu/xnu-1699.26.8/osfmk/i386/cpu_capabilities.h
FreeBSD dit que vous pouvez utiliser CLOCK_MONOTONIC_FAST
si vous désactivez le support 8-STABLE, mais Linux ne dit pas que vous pouvez utiliser CLOCK_MONOTONIC_COARSE
si vous désactivez le support pour 2.6.32.
// func now() (sec int64, nsec int32)
TEXT time·now(SB), NOSPLIT, $32
MOVL $232, AX // clock_gettime
MOVQ $0, DI // CLOCK_REALTIME
LEAQ 8(SP), SI
SYSCALL
MOVQ 8(SP), AX // sec
MOVQ 16(SP), DX // nsec
// sec is in AX, nsec in DX
MOVQ AX, sec+0(FP)
MOVL DX, nsec+8(FP)
RET
TEXT runtime·nanotime(SB), NOSPLIT, $32
MOVL $232, AX
// We can use CLOCK_MONOTONIC_FAST here when we drop
// support for FreeBSD 8-STABLE.
MOVQ $4, DI // CLOCK_MONOTONIC
LEAQ 8(SP), SI
SYSCALL
MOVQ 8(SP), AX // sec
MOVQ 16(SP), DX // nsec
// sec is in AX, nsec in DX
// return nsec in AX
IMULQ $1000000000, AX
ADDQ DX, AX
MOVQ AX, ret+0(FP)
RET
Rust
Dans la bibliothèque standard std :: time, ʻInstant :: now est fixé à
CLOCK_MONOTONICet
SystemTime :: now est fixé à
CLOCK_REALTIMEsur de nombreuses plates-formes. Pour macOS,
mach_absolute_time /
gettimeofdaysont utilisés respectivement. D'après les commentaires dans la source Ruby,
CLOCK_MONOTONIC` devrait fonctionner correctement sur Linux 2.5.63, FreeBSD 3.0, NetBSD 2.0, OpenBSD 3.4 (et pour une raison inconnue, le récent Dragonfly BSD). Pannic si l'appel système échoue.
Instant::now
mach_absolute_time (macOS/iOS)
CLOCK_MONOTONIC (Linux/Android)
SystemTime::now
gettimeofday (macOS/iOS)
CLOCK_REALTIME (Linux/Android)
rust-coarsetime crate
Si vous voulez plus de vitesse que de précision, vous pouvez utiliser rust-coarsetime. rust-coarsetime utilise respectivement CLOCK_MONOTONIC_COARSE
/ CLOCK_MONOTONIC_RAW_APPROX
/ CLOCK_MONOTONIC_FAST
sous Linux / OSX / FreeBSD (DragonflyBSD).
En tant qu'API pour l'acquisition du temps, il y a Clock.currTime
/ Clock.currStdTime
dans std.datetime de la bibliothèque standard Phobos, et vous pouvez spécifier ClockType. Les deux appellent en interne la fonction currStdTime. Lève une exception TimeException si l'appel système échoue.
L'implémentation de currStdTime en spécifiant ClockType pour chaque OS est résumée dans le tableau ci-dessous. Les OS qui ne prennent pas en charge la nouvelle API de Sierra ou qui ne sont pas sur cette branche (par exemple OpenBSD) meurent comme OS non pris en charge au moment de la compilation.
Ici, time (2) / gettimeofday (2) représente chacun un appel système, et celui de type constant est la constante passée à l'argument de clock_gettime (2).
time(2) (Linux)
time(2) (OSX)
CLOCK_SECOND (FreeBSD 8.1)
time(2) (NetBSD)
time(2) (Solaris)
CLOCK_REALTIME_COARSE (Linux 2.6.32)
gettimeofday(2) (OSX)
CLOCK_REALTIME_FAST (FreeBSD 8.1)
gettimeofday(2) (NetBSD)
CLOCK_REALTIME (Solaris)
CLOCK_REALTIME (Linux 2.5.63)
gettimeofday(2) (OSX)
CLOCK_REALTIME (FreeBSD 3.0)
gettimeofday(2) (NetBSD)
CLOCK_REALTIME (Solaris)
CLOCK_REALTIME (Linux 2.5.63)
gettimeofday(2) (OSX)
CLOCK_REALTIME_PRECISE (FreeBSD 8.1)
gettimeofday(2) (NetBSD)
CLOCK_REALTIME (Solaris)
Recommended Posts