Cancellable threading.Timer in Python

后端 未结 4 1474
南旧
南旧 2020-12-02 13:15

I am trying to write a method that counts down to a given time and unless a restart command is given, it will execute the task. But I don\'t think Python threading.Tim

4条回答
  •  青春惊慌失措
    2020-12-02 14:05

    Inspired by above post. Cancelable and Resetting Timer in Python. It uses thread.
    Features: Start, Stop, Restart, callback function.
    Input: Timeout, sleep_chunk values, and callback_function.
    Can use or inherit this class in any other program. Can also pass arguments to the callback function.
    Timer should respond in middle also. Not just after completion of full sleep time. So instead of using one full sleep, using small chunks of sleep and kept checking event object in loop.

    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()
    

提交回复
热议问题