[RUBY] Parlez de l'API d'acquisition du temps dans le langage de programmation

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 .

Python3 (3.3 ou version ultérieure)

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

  1. Utilisez CLOCK_REALTIME si vous avez clock_gettime (2)
  2. Sinon, utilisez gettimeofday (2)
  3. Sinon, utilisez le temps (2)

std::chrono::steady_clock::now

  1. Utilisez CLOCK_MONOTONIC si vous avez clock_gettime (2)
  2. Sinon, utilisez std :: chrono :: system_clock pour trouver la différence

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_MONOTONICetSystemTime :: 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

SystemTime::now

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).

Langue D

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).

Recommended Posts

Parlez de l'API d'acquisition du temps dans le langage de programmation
10 langages de programmation les plus populaires en 2020
La popularité des langages de programmation
Programmation pour combattre dans le monde ~ 5-1
Programmer pour combattre dans le monde 5-3
Obtenir l'API arXiv en Python
Fiche d'activité dans le cercle de programmation
L'histoire de la participation à AtCoder
Programmation pour combattre dans le monde - Chapitre 4
L'histoire du "trou" dans le fichier
Accéder à l'API Twitter avec Python
Tests de code dans le temps en Python
Programmation pour combattre dans le monde ~ 5-2
Si vous êtes novice en programmation, pourquoi ne pas créer un "jeu" pour le moment? L'histoire
Tendances des langages de programmation du point de vue de GitHub (mises à jour semestrielles)
Le langage de programmation le plus recherché en 2020
Essayez d'utiliser l'API Wunderlist en Python
L'histoire d'une erreur dans PyOCR
Essayez d'utiliser l'API Kraken avec Python
Tweet à l'aide de l'API Twitter en Python
MongoDB avec Python pour la première fois
API RICOH THETA S en plusieurs langues.
Dessiner des graphiques dans le langage de programmation Julia
Essayez d'accéder à l'API Spotify dans Django.
Écrire des classes (ou de type classe) dans divers langages de programmation
Essayez d'utiliser l'API BitFlyer Ligntning en Python
Animation de transition du langage de programmation le plus populaire (#programming language #popular)
J'ai essayé la programmation python pour la première fois.
Conseils pour accéder à l'API ATND avec Python
L'histoire de la recherche du n optimal dans N poing
L'histoire de la lecture des données HSPICE en Python
Boucle les variables en même temps dans le modèle
L'histoire de l'affichage des fichiers multimédias dans Django
Accédez à l'API Firebase Dynamic Links en Python
Essayez d'utiliser l'API DropBox Core avec Python
L'histoire qui s'inscrit dans l'installation de pip