2013-04-22 18 views
7

Vorrei implementare un semplice timer di controllo in pitone con due casi di utilizzo:Come implementare un timer watchdog in Python?

  • watchdog assicura che una funzione non esegue più di x secondi
  • watchdog assicura che certa funzione eseguita regolarmente effettivamente eseguito almeno ogni secondi

Come faccio?

+0

Ecco [ 'implementazione WatchdogTimer' che crea solo un thread] (https://stackoverflow.com/a/34115590/4279) – jfs

risposta

6

solo la pubblicazione di mia soluzione a questo:

from threading import Timer 

class Watchdog: 
    def __init__(self, timeout, userHandler=None): # timeout in seconds 
     self.timeout = timeout 
     self.handler = userHandler if userHandler is not None else self.defaultHandler 
     self.timer = Timer(self.timeout, self.handler) 
     self.timer.start() 

    def reset(self): 
     self.timer.cancel() 
     self.timer = Timer(self.timeout, self.handler) 
     self.timer.start() 

    def stop(self): 
     self.timer.cancel() 

    def defaultHandler(self): 
     raise self 

Utilizzo Se si vuole fare in modo la funzione termina in meno di x secondi:

watchdog = Watchdog(x) 
try: 
    # do something that might take too long 
except Watchdog: 
    # handle watchdog error 
watchdog.stop() 

Utilizzo Se si esegue regolarmente qualcosa e vuole assicurati che sia eseguito almeno ogni y secondi:

import sys 

def myHandler(): 
    print "Whoa! Watchdog expired. Holy heavens!" 
    sys.exit() 

watchdog = Watchdog(y, myHandler) 

def doSomethingRegularly(): 
    # make sure you do not return in here or call watchdog.reset() before returning 
    watchdog.reset() 
+0

Hai mai sentito parlare di PEP8? E cosa c'è "Timer()" qui? –

+0

No, non ne ho sentito parlare. Sono principiante. Ma controllerò una volta che avrò più tempo per questo ... –

+1

Non sono sicuro del tuo metodo 'reset'. Nel tuo '__init__' il tuo' Timer' passa in base a se 'userHandler' (che dovrebbe essere' non è None' BTW) viene fornito, nel qual caso viene utilizzato. In 'reset' - è sempre' self.handler' che verrà poi utilizzato ... –

1

Beh, non ho trovato un modo per interrompere un thread che è quello che volevo per il 'watchdog timer', e anche questo esempio non funziona per me. Quando eseguo

import time 
if __name__ == '__main__': 
    Watchdog(1) 
    try: 
     while True: 
      print 'Tiempo' 
      time.sleep(0.1) 
    except Watchdog: 
     print 'Error' 

Beh non succede nulla ... ottengo alcuna interruzione.

Ho aggiunto la riga 'self.timer.start()', vedo un'eccezione sollevata, ma non interrompe il thread principale. La riga "print 'Error'" non viene mai eseguita a meno che non premo Ctrl + C.

1

signal.alarm() imposta un timeout per il programma e lo si può chiamare nel vostro ciclo principale, e impostarlo alla maggiore delle due volte che siano preparati a sopportare:

import signal 
while True: 
    signal.alarm(10) 
    infloop() 
+0

Penso che funzioni solo su Unix – andy