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()

执行结果:

 

posted @ 2020-12-20 22:53  风不再来  阅读(5478)  评论(0编辑  收藏  举报