python实现定时任务的方式_Python进阶(二十八)-Python实现定时任务

Python进阶(二十八)-Python实现定时任务

前言

最近学习到了 python 中两种开启定时任务的方法,和大家分享一下心得。

sched.scheduler()

threading.Timer()

sched 定时任务

使用sched的套路如下:

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

s.enter(delay, priority, func1, (arg1, arg2, ...))

s.enter(delay, priority, func2, (arg1, arg2, arg3, ...))

s.run()

步骤如下:

第一步新建一个调度器;

第二步添加任务,可以添加多个任务;

第三步让调度器开始运行。

第二步各参数含义:

delay 相对于调度器添加这个任务时刻的延时,以秒为单位;

priority 优先级,数字越小优先级越高;

func1 任务函数

(arg1, arg2, …) 任务函数的参数

代码演示

import time

import sched

# 第一个工作函数

# 第二个参数 @starttime 表示任务开始的时间

# 很明显参数在建立这个任务的时候就已经传递过去了,至于任务何时开始执行就由调度器决定了

def worker(msg, start_time):

print (u"任务执行的时刻", time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())), "传达的消息是", msg, '任务建立时刻', start_time)

# 创建一个调度器示例

# 第一参数是获取时间的函数,第二个参数是延时函数

print (u'---------- 两个简单的例子 -------------')

print (u'程序启动时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

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

s.enter(1.0, 1, worker, ('hello', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))))

s.enter(3.0, 1, worker, ('world', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))))

s.run() # 这一个 s.run() 启动上面的两个任务

print (u'睡眠2秒前时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

time.sleep(2)

print (u'睡眠2秒结束时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

# 重点关注下面2个任务,建立时间,启动时间

# 2个任务的建立时间都很好计算,但有没有发现"hello world [3]"的启动时间比建立时间晚13秒,

# 这不就是2个sleep的总延时吗?所以说启动时间并不一定就是delay能指定的,还需要看具体的程序环境,

# 如果程序堵塞的很厉害,已经浪费了一大段的时间还没有到scheduler能调度这个任务,当scheduler能调度这个

# 任务的时候,发现delay已经过去了,scheduler为了弥补“罪过”,会马上启动这个任务。

# 任务 "hello world [15]" 就是一个很好的例子,正常情况下,程序没有阻塞的那么厉害,在scheduler能调度这个任务的时候

# 发现delay还没到就等待,如果delay时间到了就可以在恰好指定的延时调用这个任务。

print (u'\n\n---------- 两个复杂的例子 -------------')

s.enter(3, 1, worker, ('hello world [3]', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))))

print (u'睡眠7秒前时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

time.sleep(7)

print (u'睡眠7秒结束时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

s.enter(15, 1, worker, ('hello world [15]', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))))

print (u'睡眠6秒前时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

time.sleep(6)

print (u'睡眠6秒结束时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

s.run() # 过了2秒之后,启动另外一个任务

print (u'程序结束时刻', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

# 计数器,一个循环任务,总共让自己执行3次

total = 0

# 第二个工作函数,自调任务,自己开启定时并启动。

def worker2(msg, starttime):

global total

total += 1

print (u'当前时刻:', time.time(), '消息是:', msg, ' 启动时间是:', starttime)

# 只要没有让自己调用到第3次,那么继续重头开始执行本任务

if total < 3:

# 这里的delay 可以重新指定

s.enter(5, 2, worker2, ('perfect world %d' % (total), time.time()))

s.run()

print (u'程序开始时刻:', time.time())

# 开启自调任务

s.enter(5, 2, worker2, ('perfect world %d' % (total), time.time()))

s.run()

print (u'程序结束时刻:', time.time())

运行结果

0818b9ca8b590ca3270a3433284dd417.png

循环任务

任务快结束时利用scheduler又重新调用自己让自己“活过来”。

代码演示

import sched

import time

# 计数器,一个循环任务,总共让自己执行3次

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

total = 0

# 第二个工作函数,自调任务,自己开启定时并启动。

def worker2(msg, starttime):

global total

total += 1

print (u'当前时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())), '消息是:', msg, ' 启动时间是:', starttime)

# 只要没有让自己调用到第3次,那么继续重头开始执行本任务

if total < 3:

# 这里的delay可以重新指定

s.enter(5, 2, worker2, ('perfect world %d' % (total), time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))))

s.run()

print (u'程序开始时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

# 开启自调任务

s.enter(5, 2, worker2, ('perfect world %d' % (total), time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))))

s.run()

print (u'程序结束时刻:', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))

运行结果

0818b9ca8b590ca3270a3433284dd417.png

Threading.Timer() 实现定时任务

代码演示

from threading import Timer

import time

def func(msg, starttime):

print (u'程序启动时刻:', starttime, '当前时刻:', time.time(), '消息内容 --> %s' % (msg))

# 下面的两个语句和上面的 scheduler 效果一样的

Timer(5, func, ('hello', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))).start()

Timer(3, func, ('world', time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time())))).start()

运行结果

0818b9ca8b590ca3270a3433284dd417.png

Threading.Timer() 实现循环任务

代码演示

#利用 threading.Timer() 建立的自调任务

count = 0

def loopfunc(msg,start_time):

global count

print (u'启动时刻:', start_time, ' 当前时刻:', time.time(), '消息 --> %s' % (msg))

count += 1

if count < 3:

Timer(3, loopfunc, ('world %d' % (count), time.time())).start()

Timer(3, loopfunc, ('world %d' % (count), time.time())).start()

运行结果

0818b9ca8b590ca3270a3433284dd417.png

如何实现某一时刻执行任务

先求出目标时间和当前时间的时间戳差值,再调用sleep或设置延时参数。

有关Python中时间戳的计算详见博文《Python进阶(二十九)-Python时间&日期&时间戳处理》。

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值