单线程多定时任务
前言:公司业务需求,实例当中大量需要启动定时器的操作;大家都知道python中的定时器用的是threading.Timer,每当启动一个定时器时,程序内部起了一个线程,定时器触发执行结束后,线程自动销毁;这里就涉及到一个问题,如果同时有大量启动定时器的需求时,内部线程过多,程序肯定就崩了,有没有启一个线程就能完成定时器的操作呢?网上查了一些资料,还没有看到能解决目前问题的现成代码,不如自己搞一个试试
1、初始版本:
思路:定时器,说白了就是延时执行指定的程序,目前自己重构python里面的定时器不太现实,能力达不到,所以延时操作时还得用到系统定时器,不过我们可以改一下规则;把所有要进行定时操作的程序添加到特定列表中,把列表中定时时间最短程序拿出来,进行threading.Timer(time,callback)绑定,等时间超时触发自定义的callback,执行刚刚列表取出的程序;然后把时间更新,再次把列表中时间最短的程序拿出了,继续threading.Timer绑定,不断的迭代循环;当有新的定时任务加入到列表时,把当前的threading.Timer绑定取消,更新列表中的时间,再次取出最短时间,进行threading.Timer绑定......
代码:
import threading
import time
class Timer():
'''单线程下的定时器'''
def __init__(self):
self.queues = []
self.timer = None
self.last_time = time.time()
def start(self):
item = self.get()
if item:
self.timer = threading.Timer(item[0],self.execute)
self.timer.start()
def add(self,item):
print('add',item)
self.flush_time()
self.queues.append(item)
self.queues.sort(key=lambda x:x[0])
if self.timer:
self.timer.cancel()
self.timer = None
self.start()
def get(self):
item = None
if len(self.queues) > 0:
item = self.queues[0]
return item
def pop(self):
item = None
if len(self.queues) > 0:
item = self.queues.pop(0)
return item
def flush_time(self):
curr_time = time.time()
for i in self.queues:
i[0]