it-swarm.com.de

Wie genau ist time.Sleep () von Python?

Ich kann ihm Fließkommazahlen geben, wie

time.sleep(0.5)

aber wie genau ist das? Wenn ich es gebe

time.sleep(0.05)

wird es wirklich etwa 50 ms schlafen?

70
Claudiu

Die Genauigkeit der time.sleep-Funktion hängt von der Schlafgenauigkeit Ihres Betriebssystems ab. Bei Nicht-Echtzeitbetriebssystemen wie einem Standard-Windows beträgt das kleinste Intervall, für das Sie schlafen können, etwa 10-13 ms. Ich habe genaue Schlafzustände innerhalb einiger Millisekunden dieser Zeit gesehen, wenn sie über dem Minimum von 10-13 ms liegen.

Update: Wie in den unten aufgeführten Dokumenten erwähnt, ist es üblich, den Schlaf in einer Schleife auszuführen, die sicherstellt, dass Sie wieder einschlafen, wenn Sie frühzeitig aufgeweckt werden.

Ich sollte auch erwähnen, dass Sie unter Ubuntu einen Pseudo-Echtzeitkernel (mit dem RT_PREEMPT-Patch-Set) ausprobieren können, indem Sie das rt-Kernelpaket (zumindest in Ubuntu 10.04 LTS) installieren.

BEARBEITEN: Nicht-Echtzeit-Linux-Kernel für Korrekturen haben ein Mindestintervall von weniger als 1 ms und nicht mehr als 10 ms, es ist jedoch nicht deterministisch.

63
Joseph Lisee

Die Leute haben recht mit den Unterschieden zwischen Betriebssystemen und Kerneln, aber ich sehe keine Granularität in Ubuntu und ich sehe eine 1 ms-Granularität in MS7. Eine andere Implementierung von time.sleep vorschlagen, nicht nur eine andere Tickrate. Bei genauerer Betrachtung wird übrigens eine 1μs-Granularität in Ubuntu vorgeschlagen, aber das liegt an der Funktion time.time, die ich zum Messen der Genauigkeit verwende.Linux and Windows typical time.sleep behaviour in Python

45
Wilbert

Aus der Dokumentation :

Andererseits ist die Genauigkeit von time() und sleep() besser als ihre Unix-Entsprechungen: Zeiten werden als Gleitkommazahlen ausgedrückt, time() gibt die genaueste verfügbare Zeit zurück (unter Verwendung von Unix gettimeofday, sofern verfügbar), und sleep() akzeptiert a Zeit mit einem Bruchteil ungleich Null (Unix select wird verwendet, um dies zu implementieren, sofern verfügbar).

Und genauer w.r.t. sleep():

Unterbrechen Sie die Ausführung für die angegebene Anzahl von Sekunden. Das Argument kann eine Gleitkommazahl sein, um eine genauere Ruhezeit anzugeben. Die tatsächliche Suspendierungszeit kann kürzer sein als die angeforderte, da jedes aufgefangene Signal die sleep() beendet, nachdem die Auffangroutine dieses Signals ausgeführt wurde. Außerdem kann die Suspendierungszeit länger sein als in einem beliebigen Betrag angefordert, da andere Aktivitäten im System geplant sind.

26
Stephan202

Warum findest du 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

Um es festzuhalten, erhalte ich einen Fehler von ca. 0,1 ms auf meinem HTPC und 2 ms auf meinem Laptop, beide Linux-Maschinen.

14
Ants Aasma

Hier ist mein Follow-up zu Wilberts Antwort: Dasselbe gilt für Mac OS X Yosemite, da es noch nicht viel erwähnt wurde.Sleep behavior of Mac OS X Yosemite

Es sieht so aus, als ob die Schlafzeit etwa 1,25 Mal so hoch ist, wie Sie es wünschen, und manchmal schläft es zwischen 1 und 1,25 Mal so oft, wie Sie es wünschen. Es schläft fast nie (~ zweimal von 1000 Proben) deutlich mehr als das 1,25fache der von Ihnen gewünschten Zeit. 

Auch (nicht explizit dargestellt) scheint die 1.25-Beziehung ziemlich gut zu gelten, bis Sie unter 0,2 ms fallen, woraufhin sie etwas unscharf wird. Außerdem scheint sich die tatsächliche Zeit auf etwa 5 ms zu verlängern, als Sie anfordern, nachdem die angeforderte Zeit 20 ms überschreitet.

Wiederum scheint es sich bei OS X um eine völlig andere Implementierung von sleep() zu handeln, als unter Windows oder der Linux-Kernel Wilbert, die verwendet wurde.

13
Tim Supinie

Sie können nicht wirklich etwas über den Schlaf garantieren (), es sei denn, Sie werden sich mindestens so lange bemühen, so lange Sie es gesagt haben (Signale können Ihren Schlaf töten, bevor die Zeit abgelaufen ist, und viele andere Dinge können dazu führen, dass es läuft.) lange).

Das Minimum, das Sie auf einem Standard-Desktop-Betriebssystem erhalten können, liegt sicher bei 16 ms (Timer-Granularität plus Zeit für Kontextwechsel), aber die Wahrscheinlichkeit, dass die prozentuale Abweichung vom angegebenen Argument von Bedeutung ist, wird beim Versuch erheblich sein 10 Sekunden Millisekunden schlafen. 

Signale, andere Threads, die den GIL enthalten, Kernel-Scheduling-Spaß, Prozessor-Speed-Steping usw. können alle die gesamte Dauer des Threads/Prozesses beeinträchtigen.

2
Nick Bastin

Eine kleine Korrektur, einige Leute erwähnen, dass der Schlaf durch ein Signal frühzeitig beendet werden kann. In die 3.6-Dokumente heißt es

In Version 3.5 geändert: Die Funktion schläft jetzt mindestens Sekunden, selbst wenn der Schlaf wird durch ein Signal unterbrochen, es sei denn, der Signalhandler wirft eine Ausnahme aus (Begründung siehe PEP 475).

2
user405

Dies wurde kürzlich auf Python 3.7 unter Windows 10 getestet. Die Präzision lag bei etwa 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 von sleep () zu übergeben. Sie müssen die Berechnung direkt in sleep () einfügen.


Und die Rückkehr meines Terminals

17: 20: 16,891

17: 20: 18.891

3: 17: 20: 20,891

17: 20: 22,891

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

0
forrest