python循环定时任务

python循环定时任务

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

方法1. 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设的很大很大,几十分钟或者几小时。或者直接换个方法吧

方法2. 重写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的使用.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值