【问题标题】:python timer thread shutdownpython定时器线程关闭
【发布时间】:2016-05-11 21:37:33
【问题描述】:

我正在尝试创建一个可以随时退出的计时器工作线程。 python有一个内置定时器,它的回调函数只被调用一次?! 不知道为什么叫定时器。

然后我必须在工作线程中休眠,这是个坏主意。 timerThread.cancel() 无法关闭工作线程。如果我使用事件退出工作线程,工作线程只有在唤醒后才能退出。

我期待一个计时器工作线程,它可以随时退出。而且我不希望工作线程被阻塞。

有没有办法实现?

def Show():
    while 1:
        time.sleep(10)
        print("Nice!")

if __name__ == '__main__':

    timerThread = threading.Timer(1,Show)
    timerThread.start()
    while 1:
        input = str(sys.stdin.readline())
        if input == 'EXIT\n':
            timerThread.cancel()
            break;

【问题讨论】:

    标签: python multithreading timer


    【解决方案1】:

    就您而言,python 中的 Timer 对象 [1] 只运行一次,然后在一段时间后执行一个函数。但是,该函数可以启动一个新的 Timer 对象。下面是这个实现的一个例子。

    timerThread = None
    
    def timesUp():
        global timerThread
        print('Nice!')
        timerThread = Timer(10, timesUp)
        timerThread.start()
    
    def main():
        global timerThread
        timerThread = Timer(10, timesUp)
        timerThread.start()
        while 1:
            input = str(sys.stdin.readline())
            if input == 'EXIT\n':
                timerThread.cancel()
                break;
    

    总体而言,由于 python 中的 GIL [2] 问题,您将遇到正确线程的问题,因为一次只有 1 个线程可以访问解释器。这就是为什么 python 中的许多框架都是单线程、异步框架(例如 gevent [3]、tornado [4])。他们不使用线程,而是在 IOLoop(eventlets、epoll)上进行侦听,并合作将操作流让给其他等待的协程。

    [1] - https://docs.python.org/2/library/threading.html#timer-objects

    [2] - https://wiki.python.org/moin/GlobalInterpreterLock

    [3] - http://www.gevent.org/

    [4] - http://www.tornadoweb.org/en/stable/

    【讨论】:

    • timerThread.cancel() 不起作用。工作线程仍在工作
    • 我真的不明白,如果Timer只执行一次,为什么叫timer???!!!
    • 我不知道这个词的起源,但计时器可以被认为是类似于鸡蛋计时器的东西。在这几秒钟后,铃声响起。它不会自行重置,它需要您重置它。与此类似,这个定时器每次都需要你设置。
    【解决方案2】:

    你可以使用这个类来解决你的问题。

    import time
    from threading import Thread
    
    class Timer(Thread):
        def __init__(self, seconds, callback, *args, **kwargs):
            Thread.__init__(self)
    
            assert callable(callback)
            self.__callback = callback
            self.__seconds = seconds
            self.__args = args
            self.__kwargs = kwargs
    
            self.running = False
    
        def run(self):
            self.running = True
            while self.running:
                Thread(target=self.__callback, args=self.__args, kwargs=self.__kwargs).start()
                time.sleep(self.__seconds)
    
        def stop(self):  
            self.running = False
    

    要调用此函数,请使用

    def Test(spam,eggs=10):
         print spam, eggs
    
    timerFunction = Timer(1,Test,10,eggs=99) # The number 1 is the time in seconds
    timerFunction.start()
    

    停止执行使用:

    timerFunction.stop()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多