2012-04-04 3 views
1

Mein Programm nimmt eine Messung einmal pro Schleife und schläft für eine bestimmte Menge, in diesem Fall 10 Sekunden. Es misst auch die Zeit. Es misst die Zeit auf zwei Arten. Einmal mit time.straftime und noch einmal mit time.clock(). Auf den meisten meiner Computer sind diese Ergebnisse völlig konsistent und ich habe keine Probleme. Auf einem Computer stimmen sie überhaupt nicht überein.time.clock und time.strftime Geben Sie völlig verschiedene Ergebnisse

Hier ist das Code-Segment in Frage. In meinem Programm lief es unabhängig in drei Threads. self.delay ist ein Float, der die vom Benutzer angegebene Verzögerung hält, in diesem Fall 10,0 Sekunden.

cycles = 0 
    startTime = time.clock() 
    while(blah) 
     cycleBeginTime = time.clock() 
     ... 

     t = time.strftime("%Y-%m-%d %H:%M:%S") 

     ... 

     cycles += 1 
     cycleEndTime = time.clock() 
     wakeUp = startTime + cycles * self.delay 

     if cycleEndTime > wakeUp: #we overslept 
      continue 
     else: 
      #not guaranteed to sleep for the exact specified amount of time 
      time.sleep(float(wakeUp - cycleEndTime)) 
     afterSleepTime = time.clock() 
     print ("sleep(" + str(wakeUp - cycleEndTime) + ") lasted " + 
       str(afterSleepTime - cycleEndTime) +" seconds\n" + 
       "Total time for this cycle: " + 
       str(afterSleepTime - cycleBeginTime) + 
       "\ntime from start of cycle to sleep " + 
       str(cycleEndTime-cycleBeginTime)) 

Hier sind die Ergebnisse auf der Konsole für die Zeit gemessen mit time.clock. Überspringen Sie den nächsten Teil für eine Zusammenfassung.

sleep(9.8107975515) lasted 4.31354512806 seconds 
Total time for this cycle: 4.50274184753 
time from start of cycle to sleep 0.189196719463 
sleep(9.83803382537) lasted 4.35964227608 seconds 
Total time for this cycle: 4.5216022856 
time from start of cycle to sleep 0.161960009523 
sleep(9.83973893539) lasted 4.36409510551 seconds 
Total time for this cycle: 4.52435043356 
time from start of cycle to sleep 0.160255328054 

sleep(15.3537603228) lasted 5.42625884166 seconds 
Total time for this cycle: 5.56417636459 
time from start of cycle to sleep 0.137917522931 
sleep(15.3879203849) lasted 5.45131225502 seconds 
Total time for this cycle: 5.5384287755 
time from start of cycle to sleep 0.0871165204752 
sleep(15.3801304296) lasted 5.45686671345 seconds 
Total time for this cycle: 5.55443364994 
time from start of cycle to sleep 0.0975669364944 

sleep(19.7024141096) lasted 2.5903386547 seconds 
Total time for this cycle: 2.81485116786 
time from start of cycle to sleep 0.224512513157 
sleep(19.7236584582) lasted 2.61606277881 seconds 
Total time for this cycle: 2.81505236078 
time from start of cycle to sleep 0.198989581976 
sleep(19.7569903213) lasted 2.64424758408 seconds 
Total time for this cycle: 2.8228942459 
time from start of cycle to sleep 0.178646661821 

sleep(26.8608515814) lasted 3.1923968974 seconds 
Total time for this cycle: 3.44044448649 
time from start of cycle to sleep 0.248047589093 
sleep(26.9264651571) lasted 3.24803654453 seconds 
Total time for this cycle: 3.42464766929 
time from start of cycle to sleep 0.176611124756 
sleep(26.9123819307) lasted 6.19344847627 seconds 
Total time for this cycle: 6.39064386998 
time from start of cycle to sleep 0.197195393715 

sleep(30.50445713) lasted 11.3544706882 seconds 
Total time for this cycle: 11.5452852063 
time from start of cycle to sleep 0.190814518069 
sleep(30.5479180492) lasted 11.4011029222 seconds 
Total time for this cycle: 11.5583578442 
time from start of cycle to sleep 0.157254922059 
sleep(30.5384771841) lasted 11.3943939803 seconds 
Total time for this cycle: 11.5739287254 
time from start of cycle to sleep 0.179534745126 

sleep(29.032023896) lasted 9.57638019147 seconds 
Total time for this cycle: 9.6907935091 
time from start of cycle to sleep 0.114413317628 
sleep(28.9997437096) lasted 9.55454254173 seconds 
Total time for this cycle: 9.70431450053 
time from start of cycle to sleep 0.149771958799 
sleep(29.0315669415) lasted 9.57838381284 seconds 
Total time for this cycle: 9.69044695504 
time from start of cycle to sleep 0.112063142198 

sleep(29.2684610421) lasted 11.5343751591 seconds 
Total time for this cycle: 11.7100907949 
time from start of cycle to sleep 0.175715635808 
sleep(29.4380200767) lasted 11.7063676658 seconds 
Total time for this cycle: 11.7231073229 
time from start of cycle to sleep 0.01673965716 
sleep(29.2840066914) lasted 11.5395576362 seconds 
Total time for this cycle: 11.7081641622 
time from start of cycle to sleep 0.168606525989 

Hier ist eine Zusammenfassung der mit time.strftime genommen Zeitstempeln, im Vergleich zu den Messungen von time.clock und der versuchten Schlafzeit.

2012-04-04 17:22:07 
2012-04-04 17:22:17 (diff 10s. Attempted sleep time 10s time.clock says 4.5s) 
2012-04-04 17:22:32 (diff 15s. Attempted sleep time 15.4s time.clock says 5.4s) 
2012-04-04 17:22:52 (diff 20s. Attempted sleep time 19.7s time.clock says 2.8s) 
2012-04-04 17:23:46 (diff 54s. Attempted sleep time 27s time.clock says 3.4s) 
2012-04-04 17:24:16 (diff 30s. Attempted sleep time 30.5s time.clock says 11.5s) 
2012-04-04 17:24:45 (diff 29s. Attempted sleep time 29s time.clock says 9.7s) 
2012-04-04 17:25:15 (diff 30s. Attempted sleep time 29.4s time.clock says 11.7s) 

Wie Sie sehen können, stimmt time.strftime mit Schlaf die meisten, aber nicht alle von der Zeit (sie nicht einverstanden sind auf 2012.04.04 17.23.46), während time.clock völlig falsch Unsinn gibt die ganze Zeit. Gibt es etwas, das dazu führen würde, dass diese beiden Funktionen zu völlig unsinnigen Ergebnissen führen?

BEARBEITEN: Post total für kurze Zeit neu geschrieben.

EDIT: Nun, ich habe eine Lösung, aber ich verstehe nicht warum. This page sagt, dass time.clock() Wall-Uhrzeit gibt, wenn sie unter Windows verwendet wird, aber CPU-Zeit, wenn sie unter Unix verwendet wird. Einer der Antworter, der seitdem seinen Post gelöscht hat, sagte fälschlicherweise, dass time.clock() CPU-Zeit ist, aber ich frage mich, ob er trotz der Docs korrekt sein könnte. Wenn ich alle meine Aufrufe von time.clock() durch Aufrufe von time.time() ersetzt habe, funktioniert mein Programm jetzt auch auf dem Problemcomputer.

+0

Wie sieht die Ausgabe auf einem Computer aus, wo es funktioniert? – agf

+0

Auf einem Computer, auf dem es funktioniert, liegt die Messung von time.clock innerhalb von etwa 10 Millisekunden von der angegebenen Ruhezeit und von sleep, time.clock() und time.Strftzeit stimmen alle überein. – Strill

+0

Hast du CPython direkt von http://python.org installiert oder ist es eine Distribution, die mit 'time.clock' etwas anderes macht? Welche Version von Python? – agf

Antwort

0

Der beste Weg, dies zu bedenken, wenn man bedenkt, dass Schlaf- oder Timer-Funktionen einer Anwendung nicht korrekt sind, besteht darin, Zeitstempel und eine Zielzeit zu verwenden.

Legen Sie also die Zielzeit gleich EPOCH + ExecuteTime fest, legen Sie das Intervall auf eine kleine Zahl fest, aber nicht zu klein, um nicht benötigte Zyklen zu vermeiden. Und dann ist Ihr Teil der Schleife, um die Ausführungszeit zu überprüfen, wie man es überprüft.

Sie wissen, wenn eine Anwendung für nur eine Millisekunde hängt? Es überprüft Timeouts nicht gegen die tatsächliche Zeit, zu der es initiiert wurde, es glaubt nur, dass es dort fortgesetzt wurde, wo es aufgehört hat.

+0

Das ist eine vernünftige Lösung, aber ich würde gerne wissen, was könnte das verursachen, damit ich nicht verstehe wieder von ihm abgeworfen. Dies verursachte in einem mehrwöchigen Projekt fast ein großes Desaster. Was ich sagen will, ist, dass ein Unterschied von einigen Millisekunden für meine Zwecke gut ist, aber um 30 Sekunden zu sein ist zu viel. – Strill

+0

Ich denke, das ist eine schreckliche Lösung. Es steht im Gegensatz zu allem, was Menschen in der jüngsten Vergangenheit gelehrt wurden, obwohl es in der Tat eine pragmatische Umgehungslösung sein könnte. – 0xC0000022L

+0

Das ist die einzige Lösung für genaue Timer, Timer-Funktionen in jeder Sprache sind ungenau. Ich schrieb ein Spiel und wir mussten unsere eigene Timer-Funktion entwerfen, um genau zu sein und genau so mussten wir es in C++ machen. In letzter Zeit musste ich auch einen Timer für eine Website entwerfen, der genau war, und ich musste diese Methode auch für vollständige Genauigkeit verwenden. Der Grund, warum es ausgeschaltet ist, ist wie gesagt, manchmal kann ein Thread aus verschiedenen Gründen hängen und es kompensiert nicht durch Überprüfung, dass die CPU-Zyklen fortgeschritten sind. –

0

Hat der fehlerhafte PC eine Multi-Core-CPU? Vor 3.2 war es möglich, eine Situation zu bekommen, in der ein Thread auf einen Kern gesetzt wurde, die GIL freigab und bevor ein anderer Thread, der dem anderen Kern zugewiesen war, die GIL bekommen konnte, die der erste Thread wieder erworben hatte. Weitere Details finden Sie unter this post.

Update:

Eine wenig mehr Forschung zeigt, dass time.clock und time.time nicht notwendigerweise die gleiche Taktzeit zu messen verwenden. Wie Sie herausgefunden haben, besteht die Lösung darin, das eine oder das andere auszuwählen und dieses dann zu verwenden. Sie sollten einige Tests durchführen, um zu sehen, welche die beste Stabilität bietet.

+0

Nein, es ist Single-Core. In der Tat sind diejenigen, die es gut funktioniert zufällig Multi-Core. Außerdem habe ich meinen Beitrag neu geschrieben, um ihn übersichtlicher zu halten und einige neue Informationen einzubeziehen, die ich überprüft habe. – Strill