Antworten:
Die Genauigkeit der time.sleep-Funktion hängt von der Schlafgenauigkeit Ihres zugrunde liegenden Betriebssystems ab. Für Nicht-Echtzeit-Betriebssysteme wie Standard-Windows beträgt das kleinste Intervall, in dem Sie schlafen können, etwa 10-13 ms. Ich habe innerhalb einiger Millisekunden nach dieser Zeit einen genauen Schlaf gesehen, wenn er über dem Minimum von 10-13 ms lag.
Update: Wie in den unten genannten Dokumenten erwähnt, ist es üblich, den Schlaf in einer Schleife durchzuführen, die sicherstellt, dass Sie wieder einschlafen, wenn Sie früh aufgeweckt werden.
Ich sollte auch erwähnen, dass Sie unter Ubuntu einen Pseudo-Echtzeit-Kernel (mit dem RT_PREEMPT-Patch-Set) ausprobieren können, indem Sie das RT-Kernel-Paket installieren (zumindest in Ubuntu 10.04 LTS).
BEARBEITEN: Korrektur Nicht-Echtzeit-Linux-Kernel haben ein Mindestschlafintervall, das viel näher bei 1 ms als 10 ms liegt, aber nicht deterministisch variiert.
sleep()
aus den Dokumenten zu tun andere Aktivität im System ".
Die Leute haben völlig Recht mit den Unterschieden zwischen Betriebssystemen und Kerneln, aber ich sehe keine Granularität in Ubuntu und ich sehe eine Granularität von 1 ms in MS7. Schlagen Sie eine andere Implementierung von time.sleep vor, nicht nur eine andere Tickrate. Eine genauere Betrachtung deutet übrigens auf eine Granularität von 1 μs in Ubuntu hin, aber das liegt an der time.time-Funktion, die ich zum Messen der Genauigkeit verwende.
Aus der Dokumentation :
Andererseits ist die Genauigkeit von
time()
undsleep()
besser als ihre Unix-Äquivalente: Zeiten werden als Gleitkommazahlen ausgedrückt, gebentime()
die genaueste verfügbare Zeit zurück (unter Verwendung von Unix, soferngettimeofday
verfügbar) undsleep()
akzeptieren eine Zeit mit einem Bruchteil ungleich Null (Unixselect
wird verwendet) um dies umzusetzen, sofern verfügbar).
Und insbesondere bzgl sleep()
:
Unterbrechen Sie die Ausführung für die angegebene Anzahl von Sekunden. Das Argument kann eine Gleitkommazahl sein, um eine genauere Ruhezeit anzuzeigen. Die tatsächliche Suspendierungszeit kann kürzer als die angeforderte sein, da jedes abgefangene Signal die
sleep()
folgende Ausführung der Abfangroutine dieses Signals beendet . Außerdem kann die Suspendierungszeit aufgrund der Planung anderer Aktivitäten im System länger sein als um einen beliebigen Betrag angefordert.
Hier ist meine Fortsetzung von Wilberts Antwort: Dasselbe gilt für Mac OS X Yosemite, da es noch nicht viel erwähnt wurde.
Es sieht so aus, als würde es die meiste Zeit ungefähr das 1,25-fache der von Ihnen angeforderten Zeit und manchmal das 1- bis 1,25-fache der von Ihnen angeforderten Zeit schlafen. Es schläft fast nie (~ zweimal von 1000 Proben) deutlich mehr als das 1,25-fache der von Ihnen gewünschten Zeit.
Auch (nicht explizit gezeigt) scheint die 1,25-Beziehung ziemlich gut zu halten, bis Sie unter etwa 0,2 ms kommen, wonach es anfängt, ein wenig unscharf zu werden. Darüber hinaus scheint sich die tatsächliche Zeit auf etwa 5 ms länger einzustellen, als Sie anfordern, nachdem die angeforderte Zeit über 20 ms liegt.
Auch hier scheint es sich um eine völlig andere Implementierung von sleep()
OS X zu handeln als unter Windows oder dem Linux-Kern, den Wilbert verwendet hat.
Warum findest du es nicht heraus:
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
Für die Aufzeichnung erhalte ich ungefähr 0,1 ms Fehler auf meinem HTPC und 2 ms auf meinem Laptop, beide Linux-Maschinen.
Eine kleine Korrektur, mehrere Leute erwähnen, dass der Schlaf durch ein Signal vorzeitig beendet werden kann. In den 3.6-Dokumenten heißt es:
In Version 3.5 geändert: Die Funktion wird jetzt mindestens Sekunden lang in den Ruhezustand versetzt, selbst wenn der Ruhezustand durch ein Signal unterbrochen wird, es sei denn, der Signalhandler löst eine Ausnahme aus ( Begründung siehe PEP 475 ).
Sie können nicht wirklich etwas über Schlaf garantieren (), außer dass es zumindest die beste Anstrengung macht, zu schlafen, solange Sie es gesagt haben (Signale können Ihren Schlaf töten, bevor die Zeit abgelaufen ist, und viele andere Dinge können ihn zum Laufen bringen lange).
Sicherlich beträgt das Minimum, das Sie auf einem Standard-Desktop-Betriebssystem erreichen können, etwa 16 ms (Timer-Granularität plus Zeit bis zum Kontextwechsel), aber es besteht die Möglichkeit, dass die prozentuale Abweichung vom angegebenen Argument beim Versuch erheblich ist für 10s Millisekunden schlafen.
Signale, andere Threads, die die GIL enthalten, Spaß beim Planen des Kernels, Steigern der Prozessorgeschwindigkeit usw. können mit der Dauer, in der Ihr Thread / Prozess tatsächlich schläft, Chaos anrichten.
Dies wurde kürzlich unter Python 3.7 unter Windows 10 getestet. Die Genauigkeit betrug ca. 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()
Verwenden Sie keine Variable, um das Argument sleep () zu übergeben. Sie müssen die Berechnung direkt in sleep () einfügen.
Und die Rückkehr meines Terminals
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 ──────────────────────