利用Python内置sched模块实现定时任务管理

定时任务管理是编程常见需求

我们会经常遇到需要定时任务的应用场景。如定时备份数据库,定时发送短信、发布订阅信息等场景。使用Window的任务管理器,Linux的crontab管理定时任务,需要手工来添加,配置工作量多而且无法满足自动化添加定时任务场景。当然可以通过第3方库celery 来实现定时任务管理,但celery使用较复杂,需要额外的开发工作量。
好消息是,python标准库提供了1个内置模块 sched 来管理定时任务,不依赖任何第3方库,而且使用简捷。 sched模块的另一个好处在于它与平台无关,可以在任何操作系统上运行。

使用 sched 管理定时任务的编程步骤

1) 新建 1个 sched 对象

import sched
import time
scheduler ``=` `sched.scheduler(time.time, time.sleep)

2) 定义任务函数

任务函数包含计划要执行的工作。 如果需要在两个不同的时间需要执行不同的工作,应该将任务拆分为两个任务函数。

3) 根据 delay 秒数来设置任务运行时间

使用 sched.enter() 方法来安排任务,执行时间用从当前时间开始向后延迟的秒数来表示。

语法: scheduler.enter(delay, priority, action, argument=(), kwargs={})

参数说明:

  • delay: 延迟时间,单位为秒
  • priority: 优先级
  • action: 任务函数
  • argument: 任务函数所参数表(tuple格式)
  • kwargs 任务函数的可变参数表

4) 调用 sched.run()方法启动定时任务监控

启动schedule任务队列,每个任务时间到后,启动该任务函数。 队列中所有任务执行完成后,sched 对象才退出。

按绝对时间来添加任务:

enter()方法是根据当前时间向后延迟的秒数来添加任务。但经常我们遇到的场景是,要求在某个时间点来执行任务。

使用方法; sched.enterabs()

Syntax: scheduler.enterabs(time, priority, action, argument=(), kwargs={})

Parameters:

  • time: 任务执行的时间,可以是datetime格式,或 float格式的stimestamp 时间
  • priority: Priority value,数字越小,优先级越高。
  • action: 任务函数
  • argument: 参数tuple,

完整示例

import sched, time 
from datetime import datetime, timedelta

s = sched.scheduler(time.time, time.sleep)

def print_time(a: str='default'):
    # task function example
    print("From print_time", datetime.now(), a)

def calc_gap_second(dt: datetime):
    # get gap btw current time and input datetime, unit is second
    return dt.timestamp() - datetime.now().timestamp()

def print_some_times():
    print(datetime.now())
    t1= time.time()
    s.enter(10,1, print_time)   # 10秒后执行,优先级为1
    # 5秒后执行,优先级为2, 输入参数("test-2, ) 
    s.enter(5, 2, print_time, argument=('test_2',))  
    # 也是5秒后执行,用kwargs方式输入参数
    s.enter(5, 2, print_time, kwargs={'a': 'test_3'})
    # 预定在某个时间点执行,计算与当前时间的时差
    dt1 = datetime.strptime("2023-08-15 16:25:00:000001", "%Y-%m-%d %H:%M:%S:%f")
    s1: float = calc_gap_second(dt1)
    print("s1:",s1)
    # 根据计算好的时差来添加任务。
    s.enter(s1, 1, print_time, kwargs={'a': 'test_4'})
    # 用enterabs()方法,以时间点来添加任务
    s.enterabs(t1+6,1, print_time, kwargs={'a': 'test_5'})
    s.run()   # 启动监视任务循环
    print(time.time)

print_some_times()

output

2023-08-15 16:24:44.827923
s1: 15.162081003189087
From print_time 2023-08-15 16:24:49.830699 test_2
From print_time 2023-08-15 16:24:49.830699 test_3
From print_time 2023-08-15 16:24:50.833527 test_5
From print_time 2023-08-15 16:24:54.829681 default
From print_time 2023-08-15 16:25:00.005648 test_4

任务队列管理

查看所有任务
sched.queue 任务队例

取消任务

sched.cancel( event ) 取消单个任务,
event 是enter(), enterabs()添加任务后返回的任务对象。

e1 = scheduler.enter(1, 1, print_event,('1 st', ))

判断任务队列是否为空

shed.empty() 检查queue是否为空,如果是空,返回True.

示例

import sched
import time

scheduler = sched.scheduler(time.time, time.sleep)
  
def print_event(name):
    print('EVENT:', time.time(), name)

print ('START:', time.time())
e1 = scheduler.enter(1, 1, print_event,('1 st', ))
e2 = scheduler.enter(2, 1, print_event,(' 2nd', ))
scheduler.cancel(e1)
print("schedule queue length:", len(s.queue))
scheduler.run()

output:

START: 1580390119.54074
schedule queue length: 1
EVENT: 1580390121.5439944  2nd

高级的定时任务管理库,如 APScheduler ,可以实现更复杂的定时任务管理。

你可能感兴趣的:(python,服务器,flask,django)