Python开发【笔记】:单线程下执行多个定时任务
2017-07-27 13:45
645 查看
单线程多定时任务
前言:公司业务需求,实例当中大量需要启动定时器的操作;大家都知道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] = i[0] - (curr_time - self.last_time) self.last_time = curr_time def execute(self): # if self.timer: # self.timer.cancel() # self.timer = None item = self.pop() self.flush_time() if item: callback = item[1] args = item[0] callback(args) self.start()
执行及输出:
if __name__ == '__main__': def func(): while True: print(threading.active_count()) time.sleep(1) f1 = threading.Thread(target=func) f1.start() logging.basicConfig(level=logging.INFO,format="%(asctime)s %(message)s", datefmt="%m/%d/%Y %H:%M:%S [%A]") newtimer = NewTimer() newtimer.start() def func1(*args): logging.info('func1 %s'%args) time.sleep(5) def func2(*args): logging.info('func2 %s' % args) time.sleep(5) def func3(*args): logging.info('func3 %s' % args) time.sleep(5) def func4(*args): logging.info('func4 %s' % args) time.sleep(5) def func5(*args): logging.info('func5 %s' % args) time.sleep(5) newtimer.add([5,func1]) newtimer.add([4,func2]) newtimer.add([3,func3]) newtimer.add([2,func4]) newtimer.add([1,func5]) time.sleep(1) newtimer.add([1,func1]) newtimer.add([2,func2]) newtimer.add([3,func3]) newtimer.add([4,func4]) newtimer.add([5,func5]) # 输出 # 2 # 07/27/2017 11:26:19 [Thursday] NewTimer wait # 07/27/2017 11:26:19 [Thursday] NewTimer add notify # 07/27/2017 11:26:19 [Thursday] NewTimer add notify # 07/27/2017 11:26:19 [Thursday] NewTimer add notify # 07/27/2017 11:26:19 [Thursday] NewTimer add notify # 07/27/2017 11:26:19 [Thursday] NewTimer add notify # 07/27/2017 11:26:19 [Thursday] NewTimer start sys timer and wait # 07/27/2017 11:26:20 [Thursday] NewTimer execute notify # 4 # 07/27/2017 11:26:20 [Thursday] func5 1501125980.2175007 # 07/27/2017 11:26:20 [Thursday] NewTimer add notify # 07/27/2017 11:26:20 [Thursday] NewTimer add notify # 07/27/2017 11:26:20 [Thursday] NewTimer add notify # 07/27/2017 11:26:20 [Thursday] NewTimer add notify # 07/27/2017 11:26:20 [Thursday] NewTimer add notify # 3 # 3 # 3 # 3 # 3 # 07/27/2017 11:26:25 [Thursday] func4 1501125981.2175007 # 3 # 3 # 3 # 3 # 07/27/2017 11:26:30 [Thursday] func1 1501125981.218279 # 3 # 3 # 3 # 3 # 3 # 3 # 07/27/2017 11:26:35 [Thursday] func3 1501125982.2175007 # 3 # 3 # 3 # 3 # 07/27/2017 11:26:40 [Thursday] func2 1501125982.218279 # 3 # 3 # 3 # 3 # 3 # 07/27/2017 11:26:45 [Thursday] func2 1501125983.2175007 # 3 # 3 # 3 # 3 # 3 # 07/27/2017 11:26:50 [Thursday] func3 1501125983.218279 # 3 # 3 # 3 # 3 # 3 # 07/27/2017 11:26:55 [Thursday] func1 1501125984.2175007 # 3 # 3 # 3 # 3 # 3 # 07/27/2017 11:27:00 [Thursday] func4 1501125984.218279 # 3 # 3 # 3 # 3 # 3 # 07/27/2017 11:27:05 [Thursday] func5 1501125985.218279 # 3 # 3 # 3 # 3 # 3 # 07/27/2017 11:27:10 [Thursday] NewTimer wait
输出
注:这次无论如何测试线程数也不会蹭蹭的上涨,同时可以实现多定时器任务要求;缺点:用到了两线程,没有用到单线程去实现,第二时间精准度问题,需要等待上个定时程序执行完毕,程序才能继续运行
相关文章推荐
- Python 定时执行线程 执行任务
- python定时执行任务
- Python(14):定时执行一段任务
- Python 以一个指定的间隔定时循环执行任务
- windows创建定时任务执行python脚本
- 深入学习python (六) 用sched来定时执行任务
- 测试timeTask定时执行任务线程,修改系统时间测试的技巧
- python-定时执行任务(转)
- Python定时执行任务
- linux下执行Python项目,crontab不能定时执行任务
- Python 以一个指定的间隔定时循环执行任务
- crontab定时任务中不能执行python shell命令
- 在Android开发中,定时执行任务的3种实现方法
- C#定时 器 定时执行任务 线程
- linux 计划任务cron--怎么定时执行的指令(笔记)
- Python自动运维系列:每天凌晨定时执行特定任务
- 深入学习python (六) 用sched来定时执行任务
- 开发框架之spring执行定时任务
- Python学习笔记(二)Pytho解释器和程序开发、执行过程
- 【Python】django-celery执行定时任务