美文网首页
python循环定时任务

python循环定时任务

作者: Jessieee_Y | 来源:发表于2020-11-16 15:33 被阅读0次

    想要实现:一个函数 查看指定端口的进程是否运行正常。该函数需要每隔几分钟循环地执行。

    Timer(interval, function, args=[], kwargs={})

    最简单的方法就是在function中注册Timer, 每隔interval 产生一个线程,线程执行function,以达到循环的效果。interval的单位是秒。
    示例:

    from threading import Timer
    def hello():
    print "hello, world" 
       
    t = Timer(10.0, hello) 
    t.start() 
    
    • 我最开始用的就是这个方法,简单易懂。但是发现这样做很危险:
      Timer是threading的派生类,本质是一个thread,每次调用function就产生一个Timer线程,然后过一段时间再回收。然而,如果时间间隔较小(例如:几秒,一分钟),系统还没来得及回收线程的话,就会导致线程数增多,占用cpu和系统内存,甚至会把cpu跑满.
    • 解决方法:把interval设的很大很大,几十分钟或者几小时。或者直接换个方法吧

    重写RepeatingTimer 类的run方法

    在python2里的_Timer(相当于python3的Timer)是threading的子类。重写如下:

    from threading import _Timer
    def hello():
        print "hello, world"
    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(10.0, hello)
    t.start()
    

    为了理解以上重写的RepeatingTimer,再看_Timer的原函数:

    class _Timer(Thread):
        """Call a function after a specified number of seconds:
                t = Timer(30.0, f, args=[], kwargs={})
                t.start()
                t.cancel() # stop the timer's action if it's still waiting
        """
        def __init__(self, interval, function, args=[], kwargs={}):
            Thread.__init__(self)
            self.interval = interval
            self.function = function
            self.args = args
            self.kwargs = kwargs
            self.finished = Event()
        def run(self):
            self.finished.wait(self.interval)
            if not self.finished.is_set():
                self.function(*self.args, **self.kwargs)
            self.finished.set()
        def cancel(self):
            """Stop the timer if it hasn't finished yet"""
            self.finished.set()    
    
    • 可以看出self.finished 是一个 threading.Event 对象,其中包含一个默认值为False的flag,event.set()函数可以将flag变成True。self.finished.is_set()指的是判断该线程有没有结束,is_set()函数获取flag的值,返回True或False。
      原来的_Timer.run()只执行一次function,而RepeatingTimer.run()是一个while循环,所以只要 flag是False就会一直执行function,然后wait直到interval结束。
    • 这样的好处就是:只有一个线程在循环,不会产生多个线程(貌似对CPU占用没什么影响)。当想要结束时可以调用t.cancel()函数。
      参考: python如何让程序定时循环执行.
      Python threading中event的使用.

    相关文章

      网友评论

          本文标题:python循环定时任务

          本文链接:https://www.haomeiwen.com/subject/dhczbktx.html