受上述帖子的啓發。 在Python中可取消和重置計時器。它使用線程。
特點:開始,停止,重新啓動,回調函數。
輸入:超時,sleep_chunk值和callback_function。
可以在任何其他程序中使用或繼承此類。也可以將參數傳遞給回調函數。
計時器也應該在中間響應。不僅在完成睡眠時間之後。因此,不要使用一次完整的睡眠,而要使用小塊睡眠,並不斷檢查事件對象是否在循環中。
import threading
import time
class TimerThread(threading.Thread):
def __init__(self, timeout=3, sleep_chunk=0.25, callback=None, *args):
threading.Thread.__init__(self)
self.timeout = timeout
self.sleep_chunk = sleep_chunk
if callback == None:
self.callback = None
else:
self.callback = callback
self.callback_args = args
self.terminate_event = threading.Event()
self.start_event = threading.Event()
self.reset_event = threading.Event()
self.count = self.timeout/self.sleep_chunk
def run(self):
while not self.terminate_event.is_set():
while self.count > 0 and self.start_event.is_set():
# print self.count
# time.sleep(self.sleep_chunk)
# if self.reset_event.is_set():
if self.reset_event.wait(self.sleep_chunk): # wait for a small chunk of timeout
self.reset_event.clear()
self.count = self.timeout/self.sleep_chunk # reset
self.count -= 1
if self.count <= 0:
self.start_event.clear()
#print 'timeout. calling function...'
self.callback(*self.callback_args)
self.count = self.timeout/self.sleep_chunk #reset
def start_timer(self):
self.start_event.set()
def stop_timer(self):
self.start_event.clear()
self.count = self.timeout/self.sleep_chunk # reset
def restart_timer(self):
# reset only if timer is running. otherwise start timer afresh
if self.start_event.is_set():
self.reset_event.set()
else:
self.start_event.set()
def terminate(self):
self.terminate_event.set()
#=================================================================
def my_callback_function():
print 'timeout, do this...'
timeout = 6 # sec
sleep_chunk = .25 # sec
tmr = TimerThread(timeout, sleep_chunk, my_callback_function)
tmr.start()
quit = '0'
while True:
quit = raw_input("Proceed or quit: ")
if quit == 'q':
tmr.terminate()
tmr.join()
break
tmr.start_timer()
if raw_input("Stop ? : ") == 's':
tmr.stop_timer()
if raw_input("Restart ? : ") == 'r':
tmr.restart_timer()
這是最好的。如果你的程序沒有立即終止,那麼這將是*好的*,只有一個「你好」並且沒有任何延遲! :)你必須根據某些條件將't.cancel()'合併到'sayHello()'函數中。 'if counter == 10:t.cancel()'。那會有意義的。 – Apostolos 2018-03-01 22:45:21
對不起。即使那樣也不會很好。如果在調用'sayHello(0)'後添加任何代碼,它將在定時器測試結束前執行! (自己動手,在代碼末尾添加例如'print'Done'')。 – Apostolos 2018-03-01 23:12:36