Guten abend liebe Community
Ich habe vor ein paar Tagen angefangen Python zu lernen. Habe mir nun aus diesem Grund, folgende Übungsaufgabe gestellt: Ich versuche eine Schlaufe zu erstellen, die genau im 1 Sekunden takt wieder von vorne anfängt. Habe schon viel dazu gegoogelt und in diversen Büchern nachgeschaut. Leider hab ich nur Ansätze gefunden die immer mit einer Verzögerung von ein paar milisekunden funktionieren. Heisst, nach ein paar minuten war die angezeigte Zeit ein paar sekunden zu früh. Diese funktionierten hauptsächlich mit time.sleep und/oder mit threading.timer. Standet ihr schonmal vor diesem Problem? Wenn ja, habt ihr eine Lösung gefunden?
Ich erwarte natürlich kein fertiger Code nur etwas hilfe wie ich dieses Problem lösen könnte.
Grüsse
hexa
Schlaufe die sich genau jede Sekunde wiederhohlt
Was du beschreibst läuft letztendlich auf ein Echtzeitsystem hinaus. Dafür gibt es keine einfache Lösung.
Gerade als Anfänger würde ich dir empfehlen, dich von dem Problem erstmal zu verabschieden.
Gerade als Anfänger würde ich dir empfehlen, dich von dem Problem erstmal zu verabschieden.
Du meinst Schleife! So.
In freier Wildbahn habe ich so ein Problem, wie von dir erwogen, noch nicht gehabt. Ich will eigentlich immer, dass die Rechnungen möglichst schnell erledigt werden. Es gab das Problem schon mal und dazu auch Lösungen - ich habe es nicht getestet:
http://stackoverflow.com/questions/4745 ... -in-python
In freier Wildbahn habe ich so ein Problem, wie von dir erwogen, noch nicht gehabt. Ich will eigentlich immer, dass die Rechnungen möglichst schnell erledigt werden. Es gab das Problem schon mal und dazu auch Lösungen - ich habe es nicht getestet:
http://stackoverflow.com/questions/4745 ... -in-python
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
unter Linux würde man das Skript IMHO dann auch eher periodisch mit einer systemd Timer Unit oder einem cron-Job starten. Aber auch dann gibt's keine Garantie, dass das _genau_ nach 1s passiert.
Gruß, noisefloor
unter Linux würde man das Skript IMHO dann auch eher periodisch mit einer systemd Timer Unit oder einem cron-Job starten. Aber auch dann gibt's keine Garantie, dass das _genau_ nach 1s passiert.
Gruß, noisefloor
Vielen Dank für die schnellen Antworten
funktioniert gut, soweit das Ausgeführte nicht länger als eine Sekunde überschreiten.
Aus einem Beitrag deines Linke hab ich diese Möglichkeit gefunden:pixewakb: http://stackoverflow.com/questions/4745 ... -in-python
Code: Alles auswählen
import time
starttime=time.time()
while True:
print("tick")
time.sleep(1.0 - ((time.time() - starttime) % 1.0))
Hier nochmal ohne `sched`:
Code: Alles auswählen
from __future__ import print_function
from itertools import repeat
from time import sleep
try:
from time import monotonic as timefunc
except ImportError:
from time import time as timefunc
def repeated_call(func, delay, num_calls=None, check_interval=1e-4):
for _ in repeat(object(), num_calls):
start = timefunc()
while (timefunc() - start) < delay:
sleep(check_interval)
func()
def some_calculation():
print('Got a result at', timefunc())
def main():
repeated_call(some_calculation, delay=1, num_calls=20)
if __name__ == '__main__':
main()
@snafu: Deine Funktion hat keinen Vorteil gegenüber einem einfachen `sleep`. Du zählst die Zeit, die `func` braucht nicht mit und Dein busy-Waiting ist auch nicht genauer als das was ein sleep-Aufruf auch könnte.
Hier noch eine Lösung per Iterator.
Hier noch eine Lösung per Iterator.
Code: Alles auswählen
from itertools import count
import time
def ticks(interval):
start = time.time()
for step in count(1):
yield step
seconds = start + step * interval - time.time()
if seconds > 0:
time.sleep(seconds)
for toc in ticks(1.0):
print(toc)
Verbesserte Version:
Code: Alles auswählen
from __future__ import print_function
from time import sleep
from timeit import default_timer as timer
def repeated_call(func, num_calls, delay):
for _ in range(num_calls):
start = timer()
func()
remaining = start + delay - timer()
if remaining > 0:
sleep(remaining)
def some_calculation():
sleep(0.5)
print('Got a result at', timer())
def main():
repeated_call(some_calculation, 20, 1)
if __name__ == '__main__':
main()