Python-定时器
一. 线程定时器Timer原理
Timer最基本的理解是定时器,可以启动多个定时任务,这些定时器任务是异步执行,所以不存在等待顺序执行顺序。
定时器只能执行一次,如果需要重复执行,需要重新添加任务。
导入模块
from threading import Timer
timer = threading.Timer(interval, function, args=None, kwargs=None)
参数介绍
interval — 定时器间隔,间隔多少秒之后启动定时器任务(单位:秒);
function — 线程函数;
args — 线程参数,可以传递元组类型数据,默认为空(缺省参数);
kwargs — 线程参数,可以传递字典类型数据,默认为空(缺省参数);
from threading import Timer import time def test1(name): print('test1 {}'.format(name)) #每隔一秒会执行一次 timer2 = Timer(1, test1, ('bob', )) timer2.start() def test2(): print('test2') #前面的5是等待的时间,第三个参数是传入test1的参数,数组形式 timer = Timer(5, test1, ('alex', )) timer.start() # timer.cancel()#取消执行 test2()
执行结果:
二. Schedule(调度器)
Schedule是一个第三方轻量级的任务调度模块,可以按照秒,分,小时,日期或者自定义事件执行时间
方法格式 | 功能 |
---|---|
scheduler.enter(delay, priority, action, argument=(), kwargs={}) | 在 time 规定的时间后,执行 action 参数指定的函数,其中 argument 和 kwargs 负责为 action 指定的函数传参,priority 参数执行要执行任务的等级,当同一时间点有多个任务需要执行时,等级越高( priority 值越小)的任务会优先执行。该函数会返回一个 event,可用来取消该任务。 |
scheduler.cancel(event) | 取消 event 任务。注意,如果 event 参数执行的任务不存在,则会引发 ValueError 错误。 |
scheduler.run(blocking=True) | 运行所有需要调度的任务。如果调用该方法的 blocking 参数为 True,该方法将会阻塞线程,直到所有被调度的任务都执行完成。 |
示例如下:
import threading import time from sched import scheduler def job1(job): print('---------------执行任务:{}------------'.format(job)) def job2(job): print('---------------执行任务:{}------------'.format(job)) def job3(job): print('---------------执行任务:{}------------'.format(job)) def start_job(*jobs): #创建任务调度对象 sche = scheduler() # 指定时间后执行job函数 while True: for job in jobs: sche.enter(job['interval_time'], i, job['function'], argument=(job['job'],)) #执行所有调度的任务 sche.run() def main(): while True: print('------------------main-------------------------') time.sleep(2) #定义为线程方法传入的参数 my_list = [{'job': 'python', 'interval_time': 1, 'function': job1},{'job': 'C++', 'interval_time': 5, 'function': job2},{'job': 'Java', 'interval_time': 2, 'function': job3}] #创建线程 thread = threading.Thread(target = start_job,args =my_list) #启动线程 thread.start() main()
执行结果:
三. APScheduler(任务框架)
APScheduler是Python的一个定时任务框架,用于执行周琦或者定时任务
可以基于日期,时间间隔,及类似Linux上的定时任务crontab类型的定时任务
不仅可以添加,删除定时任务,还可以将任务存储到数据库中,实现任务的持久化,使用起来非常方便
1. APScheduler组件
(1). Job作业
Job作为APScheduler最小执行单位
创建Job时指定执行的函数,函数中所需参数,Job执行时的一些设置信息
构建说明
id:指定作业的唯一ID name:指定作业的名字 trigger:apscheduler定义的触发器,用于确定Job的执行时间,根据设置的trigger规则,计算得到下次执行此job的 时间, 满足时将会执行 executor:apscheduler定义的执行器,job创建时设置执行器的名字,根据字符串你名字到scheduler获取到执行此 job的 执行器,执行job指定的函数 max_instances:执行此job的最大实例数,executor执行job时,根据job的id来计算执行次数,根据设置的最大实例数 来确定是否可执行 next_run_time:Job下次的执行时间,创建Job时可以指定一个时间[datetime],不指定的话则默认根据trigger获取触 发时间 misfire_grace_time:Job的延迟执行时间,例如Job的计划执行时间是21:00:00,但因服务重启或其他原因导致 21:00:31才执行,如果设置此key为40,则该job会继续执行,否则将会丢弃此job coalesce:Job是否合并执行,是一个bool值。例如scheduler停止20s后重启启动,而job的触发器设置为5s执行 一次,因此此job错过了4个执行时间,如果设置为是,则会合并到一次执行,否则会逐个执行 func:Job执行的函数 args:Job执行函数需要的位置参数 kwargs:Job执行函数需要的关键字参数
2. Scheduler工作流程图
(1). Scheduler添加job流程
(2). Scheduler调度流程
实例代码:
import time import traceback from apscheduler.schedulers.background import BackgroundScheduler def python(job): print('job {}'.format(job)) def Java(job): print('job {}'.format(job)) def C(job): print('job {}'.format(job)) class Schedule(): def __init__(self): self.scheduler_jobs = [{'job_id': 'python', 'job_function': python, 'job_type': 'interval', 'job_interval_time': 1}, {'job_id': 'Java', 'job_function': Java, 'job_type': 'interval', 'job_interval_time': 10}, {'job_id': 'C', 'job_function': C, 'job_type': 'interval', 'job_interval_time': 3} ] self.scheduler = BackgroundScheduler() def start_schedule(self): try: for scheduler_job in self.scheduler_jobs: if not self.is_exist_scheduler_job(scheduler_job['job_id']): # 执行函数,执行类型,执行id,执行间隔时间,传入参数 print('---------------开始启动定时任务{}--------------'.format(scheduler_job['job_id'])) self.scheduler.add_job(scheduler_job['job_function'], scheduler_job['job_type'], id=scheduler_job['job_id'], max_instances=1, seconds=scheduler_job['job_interval_time'], args=(scheduler_job['job_id'], )) self.scheduler.start() except Exception as e: msg = traceback.format_exc() print(msg) def is_exist_scheduler_job(self, scheduler_job_id): ''' 是否存在定时任务 ''' if self.scheduler.get_job(scheduler_job_id): return True return False def main(self): while True: print('-----------main------------------') time.sleep(2) if __name__ == '__main__': obj = Schedule() obj.start_schedule() obj.main()
执行结果: