Je peux lui donner des nombres à virgule flottante, tels que
time.sleep(0.5)
mais quelle est sa précision? Si je le donne
time.sleep(0.05)
va-t-il vraiment dormir environ 50 ms?
Réponses:
La précision de la fonction time.sleep dépend de la précision du sommeil de votre système d'exploitation sous-jacent. Pour les systèmes d'exploitation qui ne sont pas en temps réel, comme un Windows standard, le plus petit intervalle de sommeil pendant lequel vous pouvez dormir est d'environ 10 à 13 ms. J'ai vu des sommeil précis en quelques millisecondes après ce moment au-dessus des 10-13 ms minimum.
Mise à jour: comme mentionné dans les documents cités ci-dessous, il est courant de faire le sommeil en boucle qui s'assurera de se rendormir si cela vous réveille tôt.
Je dois également mentionner que si vous utilisez Ubuntu, vous pouvez essayer un pseudo noyau en temps réel (avec le jeu de correctifs RT_PREEMPT) en installant le package du noyau rt (au moins dans Ubuntu 10.04 LTS).
EDIT: Correction des noyaux Linux non temps réel ont un intervalle de sommeil minimum beaucoup plus proche de 1 ms puis de 10 ms mais cela varie de manière non déterministe.
sleep()
dans la documentation "le temps de suspension peut être plus long que demandé par une quantité arbitraire en raison de la planification de autre activité du système ".
Les gens ont tout à fait raison sur les différences entre les systèmes d'exploitation et les noyaux, mais je ne vois aucune granularité dans Ubuntu et je vois une granularité de 1 ms dans MS7. Suggérant une implémentation différente de time.sleep, pas seulement un taux de tick différent. Une inspection plus approfondie suggère une granularité de 1 μs dans Ubuntu, mais cela est dû à la fonction time.time que j'utilise pour mesurer la précision.
De la documentation :
D'autre part, la précision de
time()
etsleep()
est meilleure que leurs équivalents Unix: les temps sont exprimés en nombres à virgule flottante,time()
renvoie le temps le plus précis disponible (en utilisant Unixgettimeofday
si disponible), etsleep()
acceptera un temps avec une fraction non nulle (Unixselect
est utilisé pour l'implémenter, le cas échéant).
Et plus précisément par rapport'a sleep()
:
Suspendez l'exécution pendant le nombre de secondes donné. L'argument peut être un nombre à virgule flottante pour indiquer un temps de sommeil plus précis. Le temps de suspension réel peut être inférieur à celui demandé car tout signal capturé mettra fin à l'
sleep()
exécution suivante de la routine de capture de ce signal. En outre, le temps de suspension peut être plus long que demandé par une quantité arbitraire en raison de la programmation d'autres activités dans le système.
Voici ma suite à la réponse de Wilbert: la même chose pour Mac OS X Yosemite, car elle n'a pas encore été beaucoup mentionnée.
On dirait que la plupart du temps, il dort environ 1,25 fois le temps que vous demandez et parfois entre 1 et 1,25 fois le temps que vous demandez. Il ne dort presque jamais (~ deux fois sur 1000 échantillons) de manière significative plus de 1,25 fois le temps que vous demandez.
De plus (non montré explicitement) la relation 1.25 semble assez bien tenir jusqu'à ce que vous tombiez en dessous d'environ 0,2 ms, après quoi elle commence à devenir un peu floue. De plus, le temps réel semble s'établir à environ 5 ms de plus que ce que vous demandez après que le temps demandé dépasse 20 ms.
Encore une fois, il semble être une implémentation complètement différente de sleep()
sous OS X que sous Windows ou quel que soit le noyau Linux que Wilbert utilisait.
Pourquoi ne le découvrez-vous pas:
from datetime import datetime
import time
def check_sleep(amount):
start = datetime.now()
time.sleep(amount)
end = datetime.now()
delta = end-start
return delta.seconds + delta.microseconds/1000000.
error = sum(abs(check_sleep(0.050)-0.050) for i in xrange(100))*10
print "Average error is %0.2fms" % error
Pour mémoire, j'obtiens une erreur d'environ 0,1 ms sur mon HTPC et 2 ms sur mon ordinateur portable, les deux machines Linux.
Petite correction, plusieurs personnes mentionnent que le sommeil peut être interrompu prématurément par un signal. Dans les documents 3.6, il est dit,
Modifié dans la version 3.5: La fonction dort maintenant au moins secondes même si le sommeil est interrompu par un signal, sauf si le gestionnaire de signal lève une exception (voir PEP 475 pour la justification).
Vous ne pouvez pas vraiment garantir quoi que ce soit à propos du sommeil (), sauf qu'il fera au moins un meilleur effort pour dormir tant que vous le lui avez dit (les signaux peuvent tuer votre sommeil avant la fin du temps, et bien d'autres choses peuvent le faire fonctionner. longue).
Certes, le minimum que vous pouvez obtenir sur un système d'exploitation de bureau standard sera d'environ 16 ms (granularité de la minuterie plus temps de changement de contexte), mais il y a de fortes chances que l'écart en% par rapport à l'argument fourni soit significatif lorsque vous essayez. dormir pendant 10s de millisecondes.
Les signaux, les autres threads contenant le GIL, le plaisir de la planification du noyau, le pas à pas de la vitesse du processeur, etc. peuvent tous faire des ravages avec la durée de sommeil de votre thread / processus.
J'ai testé cela récemment sur Python 3.7 sous Windows 10. La précision était d'environ 1 ms.
def start(self):
sec_arg = 10.0
cptr = 0
time_start = time.time()
time_init = time.time()
while True:
cptr += 1
time_start = time.time()
time.sleep(((time_init + (sec_arg * cptr)) - time_start ))
# AND YOUR CODE .......
t00 = threading.Thread(name='thread_request', target=self.send_request, args=([]))
t00.start()
N'utilisez pas de variable pour passer l'argument de sleep (), vous devez insérer le calcul directement dans sleep ()
Et le retour de mon terminal
1 ───── 17:20: 16.891 ────────────────────
2 ───── 17:20: 18.891 ────────────────────
3 ───── 17:20: 20.891 ────────────────────
4 ───── 17:20: 22.891 ────────────────────
5 ───── 17:20: 24.891 ────────────────────
....
689 ─── 17:43: 12.891 ─────────────────────
690 ─── 17:43: 14.890 ─────────────────────
691 ─── 17:43: 16.891 ─────────────────────
692 ─── 17:43: 18.890 ─────────────────────
693 ─── 17:43: 20.891 ─────────────────────
...
727 ─── 17:44: 28.891 ─────────────────────
728 ─── 17:44: 30.891 ─────────────────────
729 ─── 17:44: 32.891 ─────────────────────
730 ─── 17:44: 34.890 ─────────────────────
731 ─── 17:44: 36.891 ─────────────────────