Seite 1 von 1

Periodische Tasks

Verfasst: Freitag 22. Oktober 2010, 08:53
von Poseidonius
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 ...")

Re: Periodische Tasks

Verfasst: Freitag 22. Oktober 2010, 08:55
von lutz.horn
Schau doch mal im PyPI die Cron-artigen Pakete an. Interessant sieht z. B. http://pypi.python.org/pypi/croniter/ aus

Re: Periodische Tasks

Verfasst: Freitag 22. Oktober 2010, 09:54
von ntrunk
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