Periodische Tasks

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Poseidonius
User
Beiträge: 63
Registriert: Montag 23. Januar 2006, 08:58

Hallo zusammen,

ich brauche eine kleine Klasse, der ich eine Funktion übergeben kann, die dann alle n Sekunden im Hintergrund ausgeführt wird.

Implementiert habe ich bisher folgendes:

Code: Alles auswählen

import time, threading

class PeriodicTask():

    def __init__(self, period, callbackfct):
        self.period=period
        self.callbackfct=callbackfct

    def startTimer(self):
        self.timer=threading.Timer(self.period, self.restartTimer)
        self.timer.start()

    def restartTimer(self):
        self.callbackfct(1)
        self.startTimer()

if __name__ == "__main__":

    def doSomeThing(value):
      print "Callback Function running"
      print value

    A=PeriodicTask(1, doSomeThing)
    A.startTimer()
Das Ganze funktioniert auch soweit nur stört mich die mehrfache Definition des Timer Objekts ... threading.Timer(self.period, self.restartTimer). Lege ich mit dieser Implementierung nicht immer wieder neue Timer neben den bereits existierenden an?

Grüße und ein schönes Wochenende

Poseidonius

PS: Als Neuling bin ich freue ich mich über alle kritischen Anmerkungen ("so macht man das aber schon gar nicht, weil ...")
Benutzeravatar
lutz.horn
User
Beiträge: 205
Registriert: Dienstag 8. November 2005, 12:57
Wohnort: Pforzheim

Schau doch mal im PyPI die Cron-artigen Pakete an. Interessant sieht z. B. http://pypi.python.org/pypi/croniter/ aus
https://www.xing.com/go/invite/18513630.6a91d4
ntrunk
User
Beiträge: 83
Registriert: Sonntag 7. September 2008, 23:09
Wohnort: Buchen (Odenwald)

Poseidonius hat geschrieben:Lege ich mit dieser Implementierung nicht immer wieder neue Timer neben den bereits existierenden an?
Nun ja, da das Timer-Objekt keinen Restart vorsieht, ist das wohl die vorgesehene Funktionsweise. Die alten Timer werden allerdings automatisch zerstört, wenn kein Verweis darauf mehr vorhanden ist, so dass du nicht befürchten musst, dass der Speicher zugemüllt wird. Wenn dich das Neuanlegen prinzipiell stört, kannst du z.B. sleep aus dem time-Modul in einer Schleife verwenden um eine Funktion periodisch aufzurufen:

Code: Alles auswählen

import time

def do_something(n1, n2, n3):
    print n1,n2,n3

def periodic_task(counter, interval, callback, *args, **kwargs):
    while counter:
        time.sleep(interval)
        callback(*args, **kwargs)
        counter -= 1

periodic_task(10, 1, do_something, 42, 43, 44)
So läuft das allerdings auf dem Hauptthread, falls während der Wartezeit auch noch anderer Code ausgeführt werden soll, kannst du die Funktion periodic_task in einem anderen Thread ausführen:

Code: Alles auswählen

import time, threading

def do_something(n1, n2, n3):
    print n1,n2,n3

def periodic_task(counter, interval, callback, *args, **kwargs):
    while counter:
        time.sleep(interval)
        callback(*args, **kwargs)
        counter -= 1

t = threading.Thread(target=periodic_task, args=(5,1,do_something,42,43,44))
t.start()
Gruß
Norbert
Antworten