2013-07-06 15 views
7

Ich spielte mit der time.sleep-Funktion aus Python-Standard-Bibliothek und fand es nicht ausreichend für Sub-ms-Verzögerungen. Beim Testen habe ich festgestellt, dass es tatsächlich 1.1-1.2 ms für eine Wartezeit von 1 ms wartet. Die Implementierung einer hektischen Wartezeit hat die Genauigkeit auf 1% gebracht. Ich benutzte:Python time.sleep vs beschäftigt warten Genauigkeit

und konnte bis zu 0,0001 Sekunden vor 1% Genauigkeit brechen.

Die wichtigsten Fragen, die ich habe, sind:

  • Warum ist die Schlaffunktion so ungenau (möglicherweise eine C Ausgabe)? Ändert das eine bessere CPU mit einer höheren Taktfrequenz?
  • Warum sollte jemand schlafen? Der einzige Vorteil, den ich sehe, Energieeinsparung, ist auf eingebettete Systeme beschränkt, nein?
  • Wäre es möglich, die Ungenauigkeit des Schlafs durch Kalibrierung zu kompensieren? Wie so:
 
def sleep(dt): 
    sleep(calibration_function(dt)) 

Als Nebenwirkung, las ich, dass der Schlaf nicht einmal gut mit langen Wartezeiten funktioniert: Upper limit in Python time.sleep()? ich auch irgendwo auf las SO von einer Schleife von kürzeren Zeitabständen machen Präzision zu erhöhen , aber das ist nutzlos, wenn ich 0,01 Sek. verzögern möchte. Karl Voigtland erwähnt mit ctypes 'nanoschlaf, aber ich denke, das ist übertrieben und diese time.sleep sollte ihr beabsichtigtes Verhalten tun.

time.sleep ist eine defekte Python-Funktion? Oder kümmert es niemanden um genaue Zeitmessung genug?

+1

mögliche Duplikate von [Wie genau ist python time.sleep()?] (Http://stackoverflow.com/questions/1133857/how-accurate-is-pythons-time-sleep) – g19fanatic

+0

Ja, ich dachte, es war ein OS-Anruf, aber jetzt wundere ich mich, warum sie einen OS-Anruf verwenden, wenn ein beschäftigtes Warten besser ist. – JDong

+0

eine hektische Wartezeit saugt CPU-Zeit und blockiert eine CPU. Ein Sleep führt einen Kontextwechsel aus und blockiert keine andere Ausführung (es "blockiert" Ihre Ausführung). Im Allgemeinen warten Sie nur, wenn Sie wirklich das genaue Timing brauchen, und selbst dann sind Sie immer noch auf den Betriebssystembedarf für CPU beschränkt, der Sie möglicherweise wegführen könnte ... – g19fanatic

Antwort

4

Unter Windows kann die OS Sleep-Funktion (die Python unbedingt benötigt) nur einen Thread auf einem Vielfachen des aktuellen Timer-Intervalls aufwecken. Typischerweise liegt diese zwischen 1,0 ms und 15,6 ms.das Timerintervall senken kann nützlich sein, weil es für kürzere schläft erlaubt, aber es verschwendet Strom, wie ich in diesem Artikel über schrieb:

http://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/

Besetzt Warte bessere Genauigkeit geben kann, aber ist in der Regel eine schreckliche Idee, da es Abfälle noch mehr Strom und stiehlt CPU-Zeit von mehr verdient Aufgaben:

https://randomascii.wordpress.com/2012/06/05/in-praise-of-idleness/

Schließlich ist die Genauigkeit der busy waiting wird davon abhängen, welche Timer-Funktion Sie verwenden, um die aktuelle Zeit zu bekommen, und kann auch von der Timerintervall:

https://randomascii.wordpress.com/2013/05/09/timegettime-versus-gettickcount/

Warum wollen Sie für eine solche kurze Zeiträume schlafen? Normalerweise wäre es besser, auf etwas zu warten - auf ein Ereignis zu warten - anstatt auf so kurze Zeiträume zu warten.

+0

In der Tat verwendet Python 'time.sleep()' einen 'WaitForSingleObject() 'Aufruf mit einem Timeout, um Ctrl-C während des Wartens abzufangen (über' SetConsoleCtrlHandler() ', das ein Ereignis signalisiert.) – schlenk

+0

Die Anwendung ist eine Art von Makro; Ich habe eine Reihe von Aktionen, die ich sehr genau simulieren möchte. Ich habe gelernt, wie man das in C macht, habe aber die kanonische Lösung in Python noch nicht gefunden. Meine Frage ist ein wenig unbeantwortbar, also werde ich Ihre Antwort für jetzt akzeptieren. Danke für die Einsicht. – JDong

+0

@schlenk Danke für die Information über die Implementierung von time.sleep(). Die Regeln zum Ablauf des Timeouts sind grundsätzlich dieselben wie für Sleep() (weil der Scheduler nur ausgeführt wird, wenn etwas passiert oder wenn ein Timer-Interrupt ausgelöst wird), so dass die Antwort immer noch zutrifft. –

0

Dies ist eine Art doppelte Frage, aber ich werde versuchen, es hier trotzdem so gut wie möglich zu beantworten.

Die Sleep-Funktion ist ein OS-Anruf, der sich von Busy Wait dadurch unterscheidet, dass der Thread nicht blockiert wird. Wenn Sie jedoch ein Multithread-Skript haben, sollte es die anderen Threads nicht blockieren. Die Schlaffunktion ist in Windows ungenau, weil es kein Echtzeit-Betriebssystem ist (nicht sicher, was das bedeutet). Wenn Sie streng nach der Genauigkeit der Wartezeit suchen, ist beschäftigt warten, der Weg zu gehen. Ansonsten ist time.sleep() wahrscheinlich bevorzugt. Der Grund dafür, dass der OS-Aufruf in den Ruhezustand ungenau ist, liegt wahrscheinlich darin, dass er auf die Rückkehr des Betriebssystems zum richtigen Zeitpunkt angewiesen ist und von der Genauigkeit des OS-Schedulers abhängig ist.