2015-04-21 14 views

Odpowiedz

6

Użyj wątek zawierający pętlę

from threading import Thread 
import time 

def background_task(): 
    while not background_task.cancelled: 
     self.mqConn.heartbeat_tick() 
     time.sleep(30) 
background_task.cancelled = False 

t = Thread(target=background_task) 
t.start() 

background_task.cancelled = True 

Alternatywnie, można podklasy stoper, aby anulować proste:

from threading import Timer 

class RepeatingTimer(Timer): 
    def run(self): 
     while not self.finished.is_set(): 
      self.function(*self.args, **self.kwargs) 
      self.finished.wait(self.interval) 


t = RepeatingTimer(30.0, self.mqConn.heartbeat_tick) 
t.start() # every 30 seconds, call heartbeat_tick 

# later 
t.cancel() # cancels execution 
+1

To może być ważne, aby wspomnieć, że to * nie * wykonać co 30 sekund, jeśli 'heartbeat_tick()' zajmuje znaczną ilość czasu – goncalopp

+0

Tak, to wola przynajmniej przez 30 sekund za każdym razem. Co najwyżej 30 sekund jest trochę trudniejsze. – Eric

+1

Jeśli funkcja pierwszego planu była związana z procesorem, czy wątek tła byłby uniemożliwiony przez GIL? –

2

Jednym ze sposobów, aby to zrobić byłoby użyć ramy circuits aplikacji tak:

from circuits import Component, Event, Timer 


class App(Component): 

    def init(self, mqConn): 
     self.mqConn = mqConn 
     Timer(30, Event.create("heartbeat"), persist=True).register(self) 

    def heartbeat(self): 
     self.mqConn.heartbeat_tick() 


App().run() 

Uwaga: Jestem autorem obwodów :)

To jest właśnie podstawowa idea i struktura - musisz dostosować to, aby dopasować się do Twojej konkretnej aplikacji i wymagań!

1

Albo można użyć klasy Timer w module gwintowania :

from threading import Timer 

def hello(): 
    print "hello, world" 

t = Timer(30.0, hello) 
t.start() # after 30 seconds, "hello, world" will be printed 
t.cancel() # cancels execution, this only works before the 30 seconds is elapsed 

Nie rozpocznie się co X sekund, a raczej opóźnia wątek do wykonania w ciągu x sekund. Ale nadal możesz umieścić to w pętli i użyć t.is_alive(), aby zobaczyć jego status.

+0

Gdzie byłaby pętla? – Eric

+0

To zależy od przypadku użycia? – Joe

+0

Czy to też nie musi być wątek tła? – Eric

2

Szybka odpowiedź na odpowiedź Eric: nie można podklasy Timer, ponieważ w rzeczywistości jest to lekka funkcja otaczająca prawdziwą klasę: _Timer. Jeśli to zrobisz, pojawi się problem, który pojawia się w this post.

Korzystanie _Timer zamiast rozwiązuje go:

from threading import _Timer 

class RepeatingTimer(_Timer): 
    def run(self): 
     while not self.finished.is_set(): 
      self.function(*self.args, **self.kwargs) 
      self.finished.wait(self.interval) 


t = RepeatingTimer(30.0, self.mqConn.heartbeat_tick) 
t.start() # every 30 seconds, call heartbeat_tick 

# later 
t.cancel() # cancels execution