Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Python3-定时任务四种实现方式

Python3-定时任务四种实现方式

作者头像
py3study
发布于 2020-01-06 06:17:46
发布于 2020-01-06 06:17:46
2.3K00
代码可运行
举报
文章被收录于专栏:python3python3
运行总次数:0
代码可运行

老猫最近做一个小程序开发任务,主要负责后台部分开发;根据项目需求老猫需要实现三个定时任务:

1>定时更新微信token,需要2小时更新一次; 2>商品定时上线; 3>定时检测后台服务是否存活;

老猫使用Python去实现这三个任务,这里需要使用定时相关知识点; Python实现定点与定时任务方式比较多,老猫找到下面四中实现方式,每个方式都有自己应用场景;下面老猫来快速介绍Python中常用的定时任务实现方式:

1>循环+sleep; 2>线程模块中Timer类; 3>schedule模块; 4>定时框架:APScheduler

在开始之前先设定一个任务(这样不用依赖外部环境): 1:定时或者定点监测CPU与内存使用率; 2:将时间,CPU,内存使用情况保存到日志文件

先来实现系统监测功能: 准备工作:安装psutil:pip install psutil 功能实现

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#psutil:获取系统信息模块,可以获取CPU,内存,磁盘等的使用情况
import psutil
import time
import datetime
#logfile:监测信息写入文件
def MonitorSystem(logfile = None):
    #获取cpu使用情况
    cpuper = psutil.cpu_percent()
    #获取内存使用情况:系统内存大小,使用内存,有效内存,内存使用率
    mem = psutil.virtual_memory()
    #内存使用率
    memper = mem.percent
    #获取当前时间
    now = datetime.datetime.now()
    ts = now.strftime('%Y-%m-%d %H:%M:%S')
    line = f'{ts} cpu:{cpuper}%, mem:{memper}%'
    print(line)
    if logfile:
        logfile.write(line)

代码运行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2019-03-21 14:23:41 cpu:0.6%, mem:77.2%

接下来我们要实现定时监测,比如3s监测一下系统资源使用情况。

最简单使用方式:sleep

这种方式最简单,直接使用while+sleep就可以实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def loopMonitor():
    while True:
        MonitorSystem()
        #2s检查一次
        time.sleep(3)
loopMonitor()

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2019-03-21 14:28:42 cpu:1.5%, mem:77.6%
2019-03-21 14:28:45 cpu:1.6%, mem:77.6%
2019-03-21 14:28:48 cpu:1.4%, mem:77.6%
2019-03-21 14:28:51 cpu:1.4%, mem:77.6%
2019-03-21 14:28:54 cpu:1.3%, mem:77.6%

这种方式存在问题:只能处理单个定时任务。 又来了新任务:需要每秒监测网络收发字节,代码实现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
def MonitorNetWork(logfile = None):
    #获取网络收信息
    netinfo = psutil.net_io_counters()
    #获取当前时间
    now = datetime.datetime.now()
    ts = now.strftime('%Y-%m-%d %H:%M:%S')
    line = f'{ts} bytessent={netinfo.bytes_sent}, bytesrecv={netinfo.bytes_recv}'
    print(line)
    if logfile:
        logfile.write(line)
MonitorNetWork()

代码执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2019-03-21 14:47:21 bytessent=169752183, bytesrecv=1107900973

如果我们同时在while循环中监测两个任务会有等待问题,不能每秒监测网络情况。

Timer实现方式

timer最基本理解就是定时器,我们可以启动多个定时任务,这些定时器任务是异步执行,所以不存在等待顺序执行问题。 先来看Timer的基本使用: 导入:from threading import Timer 主要方法:

Timer方法

说明

Timer(interval, function, args=None, kwargs=None)

创建定时器

cancel()

取消定时器

start()

使用线程方式执行

join(self, timeout=None)

等待线程执行结束

定时器只能执行一次,如果需要重复执行,需要重新添加任务; 我们先来看基本使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from threading import Timer
#记录当前时间
print(datetime.datetime.now())
#3S执行一次
sTimer = Timer(3, MonitorSystem)
#1S执行一次
nTimer = Timer(1, MonitorNetWork)
#使用线程方式执行
sTimer.start()
nTimer.start()
#等待结束
sTimer.join()
nTimer.join()
#记录结束时间
print(datetime.datetime.now())

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2019-03-21 15:13:36.739798
2019-03-21 15:13:37 bytessent=171337324, bytesrecv=1109002349
2019-03-21 15:13:39 cpu:1.4%, mem:93.2%
2019-03-21 15:13:39.745187

可以看到,花费时间为3S,但是我们想要做的是每秒监控网络状态;如何处理。 Timer只能执行一次,所以执行完成之后需要再次添加任务,我们对代码进行修改:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from threading import Timer
import psutil
import time
import datetime
def MonitorSystem(logfile = None):
    cpuper = psutil.cpu_percent()
    mem = psutil.virtual_memory()
    memper = mem.percent
    now = datetime.datetime.now()
    ts = now.strftime('%Y-%m-%d %H:%M:%S')
    line = f'{ts} cpu:{cpuper}%, mem:{memper}%'
    print(line)
    if logfile:
        logfile.write(line)
    #启动定时器任务,每三秒执行一次
    Timer(3, MonitorSystem).start()

def MonitorNetWork(logfile = None):
    netinfo = psutil.net_io_counters()
    now = datetime.datetime.now()
    ts = now.strftime('%Y-%m-%d %H:%M:%S')
    line = f'{ts} bytessent={netinfo.bytes_sent}, bytesrecv={netinfo.bytes_recv}'
    print(line)
    if logfile:
        logfile.write(line)
    #启动定时器任务,每秒执行一次
    Timer(1, MonitorNetWork).start()
MonitorSystem()
MonitorNetWork()

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
2019-03-21 15:18:21 cpu:1.5%, mem:93.2%
2019-03-21 15:18:21 bytessent=171376522, bytesrecv=1109124678
2019-03-21 15:18:22 bytessent=171382215, bytesrecv=1109128294
2019-03-21 15:18:23 bytessent=171384278, bytesrecv=1109129702
2019-03-21 15:18:24 cpu:1.9%, mem:93.2%
2019-03-21 15:18:24 bytessent=171386341, bytesrecv=1109131110
2019-03-21 15:18:25 bytessent=171388527, bytesrecv=1109132600
2019-03-21 15:18:26 bytessent=171390590, bytesrecv=1109134008

从时间中可以看到,这两个任务可以同时进行不存在等待问题。 Timer的实质是使用线程方式去执行任务,每次执行完后会销毁,所以不必担心资源问题。

调度模块:schedule

schedule是一个第三方轻量级的任务调度模块,可以按照秒,分,小时,日期或者自定义事件执行时间; 安装方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install schedule

我们来看一个例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import datetime
import schedule
import time
def func():
    now = datetime.datetime.now()
    ts = now.strftime('%Y-%m-%d %H:%M:%S')
    print('do func  time :',ts)
def func2():
    now = datetime.datetime.now()
    ts = now.strftime('%Y-%m-%d %H:%M:%S')
    print('do func2 time:',ts)
def tasklist():
    #清空任务
    schedule.clear()
    #创建一个按秒间隔执行任务
    schedule.every(1).seconds.do(func)
    #创建一个按2秒间隔执行任务
    schedule.every(2).seconds.do(func2)
    #执行10S
    for i in range(10):
        schedule.run_pending()
        time.sleep(1)
tasklist()

执行结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
do func  time : 2019-03-22 08:51:38
do func2 time: 2019-03-22 08:51:39
do func  time : 2019-03-22 08:51:39
do func  time : 2019-03-22 08:51:40
do func2 time: 2019-03-22 08:51:41
do func  time : 2019-03-22 08:51:41
do func  time : 2019-03-22 08:51:42
do func2 time: 2019-03-22 08:51:43
do func  time : 2019-03-22 08:51:43
do func  time : 2019-03-22 08:51:44
do func2 time: 2019-03-22 08:51:45
do func  time : 2019-03-22 08:51:45
do func  time : 2019-03-22 08:51:46

执行过程分析:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
>1>因为老猫在jupyter下执行,所以先将schedule任务清空;
>2>按时间间在schedule中隔添加任务;
>3>老猫这里按照秒间隔添加func,按照两秒间隔添加func2;
>4>schedule添加任务后,需要查询任务并执行任务;
>5>为了防止占用资源,每秒查询到点任务,然后顺序执行;

第5个顺序执行怎么理解,我们修改func函数,里面添加time.sleep(2) 然后只执行func工作,输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
do func  time : 2019-03-22 09:00:59
do func  time : 2019-03-22 09:01:02
do func  time : 2019-03-22 09:01:05

可以看到时间间隔为3S,为什么不是1S? 因为这个按照顺序执行,func休眠2S,循环任务查询休眠1S,所以会存在这个问题。 在我们使用这种方式执行任务需要注意这种阻塞现象。 我们看下schedule模块常用使用方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#schedule.every(1)创建Job, seconds.do(func)按秒间隔查询并执行
schedule.every(1).seconds.do(func)
#添加任务按分执行
schedule.every(1).minutes.do(func)
#添加任务按天执行
schedule.every(1).days.do(func)
#添加任务按周执行
schedule.every().weeks.do(func)
#添加任务每周1执行,执行时间为下周一这一时刻时间
schedule.every().monday.do(func)
#每周1115开始执行
schedule.every().monday.at("12:00").do(job)

这种方式局限性:如果工作任务回非常耗时就会影响其他任务执行。我们可以考虑使用并发机制配置这个模块使用。

任务框架APScheduler

APScheduler是Python的一个定时任务框架,用于执行周期或者定时任务, 可以基于日期、时间间隔,及类似于Linux上的定时任务crontab类型的定时任务; 该该框架不仅可以添加、删除定时任务,还可以将任务存储到数据库中,实现任务的持久化,使用起来非常方便。 安装方式:pip install apscheduler apscheduler组件及简单说明:

1>triggers(触发器):触发器包含调度逻辑,每一个作业有它自己的触发器 2>job stores(作业存储):用来存储被调度的作业,默认的作业存储器是简单地把作业任务保存在内存中,支持存储到MongoDBRedis数据库中 3> executors(执行器):执行器用来执行定时任务,只是将需要执行的任务放在新的线程或者线程池中运行 4>schedulers(调度器):调度器是将其它部分联系在一起,对使用者提供接口,进行任务添加,设置,删除。

来看一个简单例子:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import time
from apscheduler.schedulers.blocking import BlockingScheduler
def func():
    now = datetime.datetime.now()
    ts = now.strftime('%Y-%m-%d %H:%M:%S')
    print('do func  time :',ts)

def func2():
    #耗时2S
    now = datetime.datetime.now()
    ts = now.strftime('%Y-%m-%d %H:%M:%S')
    print('do func2 time:',ts)
    time.sleep(2)

def dojob():
    #创建调度器:BlockingScheduler
    scheduler = BlockingScheduler()
    #添加任务,时间间隔2S
    scheduler.add_job(func, 'interval', seconds=2, id='test_job1')
    #添加任务,时间间隔5S
    scheduler.add_job(func2, 'interval', seconds=3, id='test_job2')
    scheduler.start()
dojob()

输出结果:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
do func  time : 2019-03-22 10:32:20
do func2 time: 2019-03-22 10:32:21
do func  time : 2019-03-22 10:32:22
do func  time : 2019-03-22 10:32:24
do func2 time: 2019-03-22 10:32:24
do func  time : 2019-03-22 10:32:26

输出结果中可以看到:任务就算是有延时,也不会影响其他任务执行。 APScheduler框架提供丰富接口去实现定时任务,可以去参考官方文档去查看使用方式。

最后选择:

老猫简单总结上面四种定时定点任务实现: 1:循环+sleep方式适合简答测试, 2:timer可以实现定时任务,但是对定点任务来说,需要检查当前时间点; 3:schedule可以定点定时执行,但是需要在循环中检测任务,而且存在阻塞; 4:APScheduler框架更加强大,可以直接在里面添加定点与定时任务; 综合考虑,老猫决定使用APScheduler框架,实现简单,只需要直接创建任务,并将添加到调度器中即可。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019/09/24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Server 层混杂信息字典表 | 全方位认识 information_schema(下)
该表提供查询关于表级别权限信息,该表中的内容来自mysql.tables_priv
老叶茶馆
2020/11/26
3250
Server 层混杂信息字典表 | 全方位认识 information_schema(中)
该表提供查询关于语句性能分析的信息。其记录内容对应于SHOW PROFILES和SHOW PROFILE语句产生的信息
老叶茶馆
2020/11/26
4120
Server层表级别对象字典表 | 全方位认识 information_schema
在上一篇《Server层统计信息字典表 | 全方位认识 information_schema》中,我们详细介绍了information_schema系统库的列、约束等统计信息字典表,本期我们将为大家带来系列第三篇《Server层表级别对象字典表 | 全方位认识information_schema》。
老叶茶馆
2020/11/26
1.1K0
mysql中information_schema库下的KEY_COLUMN_USAGE表详解
`information_schema.KEY_COLUMN_USAGE` 表是 MySQL 中的一个元数据表,用于存储关于表的键列信息,包括主键、唯一键以及外键的详细信息。这个表包含了关于哪些列参与了哪些类型的键约束的信息。下面是这个表的详细解释:
jack.yang
2025/04/05
910
mysql中information_schema库下的COLUMNS_EXTENSIONS表详解
`information_schema.COLUMNS_EXTENSIONS` 表是 MySQL 8.0.22 及以上版本中引入的一个元数据表,用于存储与表列相关的扩展属性。这些属性主要用于存储引擎级别的信息,例如 InnoDB 存储引擎的列属性。下面是对该表的详细解释:
jack.yang
2025/04/05
840
MySQL information_schema详解 KEY_COLUMN_USAGE
https://dev.mysql.com/doc/refman/5.7/en/key-column-usage-table.html
bsbforever
2020/08/18
1.6K0
InnoDB 层系统字典表 | 全方位认识 information_schema(IFS)
在《Server 层混杂信息字典表 | 全方位认识 information_schema》中,我们详细介绍了information_schema下的状态变量、系统变量、进程状态、字符集和校对规则等字典表,本期我们将为大家带来系列第五篇《InnoDB 层系统字典表 | 全方位认识 information_schema》,下面请跟随我们一起开始information_schema 系统库的系统学习之旅吧。
老叶茶馆
2020/11/26
9760
MySQL information_schema 系统库介绍
当我们安装好 MySQL 数据库后,会发现数据库实例自带有 information_schema 系统库,你是否有去关注过这个系统库呢?是否有查询过此库中的表数据呢?又是否清楚此库存在的具体作用呢?带着这些疑问,我们一起来看本篇文章。
MySQL技术
2021/08/24
9700
应用示例荟萃 | 全方位认识 information_schema
在上一篇《InnoDB 层压缩相关字典表 | 全方位认识information_schema》中,我们详细介绍了InnoDB层记录压缩表信息的字典表,本期我们将为大家带来系列第九篇《应用示例荟萃 | 全方位认识information_schema》,也是"全方位认识information_schema"的最后一篇,下面请跟随我们一起开始information_schema系统库的系统学习之旅吧
老叶茶馆
2020/11/26
7090
InnoDB 层压缩相关字典表 | 全方位认识 information_schema
在上一篇《InnoDB 层全文索引字典表|全方位认识 information_schema》中,我们详细介绍了InnoDB层的全文索引字典表,本期我们将为大家带来系列第八篇《InnoDB 层压缩相关字典表|全方位认识 information_schema》,下面请跟随我们一起开始 information_schema 系统库的系统学习之旅吧。
老叶茶馆
2020/11/26
4410
mysql的information_schema库下COLUMN_STATISTICS表详解
`information_schema.COLUMN_STATISTICS` 表是 MySQL 8.0.16 及更高版本中引入的一个元数据表,用于存储关于表列的统计信息,特别是直方图数据。这些统计信息有助于优化器更准确地估计查询的成本,从而选择更高效的执行计划。
jack.yang
2025/04/05
600
介绍一下 information_schema 库
今天给大家介绍一款 Mysql 中附属的数据库,就是 information_schema 数据库,为什么说是附属呢?是因为这个数据库是在安装 Mysql 的同时就会安装到你电脑上。这个数据库里面主要存储了关于数据库里面的各种库、表、列、注释等信息。这个库对我们有什么用呢?有很大用处,尤其是当一个公司没有数据字典的时候,你就可以通过查看这个数据库,然后自己去梳理字典。
张俊红
2019/06/24
1.9K0
information_schema和performance_schema的一点知识
information_schema和performance_schema的一点知识
AsiaYe
2020/02/17
2.4K0
MySQL information_schema详解 FILES
它提供InnoDB数据文件的信息,如果是NDB,它提供了有关存储了NDB集群磁盘数据表的文件的信息。
bsbforever
2020/08/18
1.4K0
MySQL内置数据库information_schema 详解
不知道大家有没有注意到,当你安装好MySQL数据库环境后,然后使用客户端连接后,会发现数据库列表不是空的,会有四个数据库(information_schema、mysql、sysperformance_schema),你有有没有对这些数据库有些好奇呢,今天先给大家聊聊MySQL内置的information_schema 数据库相关的知识,希望对大家深入了解MySQL能够提供一些帮助!
小明互联网技术分享社区
2023/12/07
5.1K1
MySQL内置数据库information_schema 详解
InnoDB 层锁、事务、统计信息字典表 | 全方位认识 information_schema
在上一篇《InnoDB 层系统字典表|全方位认识 information_schema》中,我们详细介绍了InnoDB层的系统字典表,本期我们将为大家带来系列第六篇《InnoDB 层锁、事务、统计信息字典表|全方位认识 information_schema》
老叶茶馆
2020/11/26
1.4K0
InnoDB 层全文索引字典表 | 全方位认识 information_schema
在上一篇中,我们详细介绍了InnoDB 层的锁、事务、及其相关的统计信息字典表,本期我们将为大家带来系列第七篇《InnoDB 层全文索引字典表 | 全方位认识 information_schema》。
老叶茶馆
2020/11/26
1.2K0
Server 层混杂信息字典表 | 全方位认识 information_schema(上)
在上一篇《Server层表级别对象字典表 | 全方位认识 information_schema》中,我们详细介绍了information_schema系统库的表级别对象字典表,本期我们将为大家带来系列第四篇《Server层混杂信息字典表 | 全方位认识 information_schema》,下面请跟随我们一起开始information_schema系统库的系统学习之旅吧。
老叶茶馆
2020/11/26
9540
SQL笔记(2)——MySQL的表操作与索引
查看MySQL数据库中特定表的详细设计信息,可以使用DESCRIBE命令,该命令可以显示出表中所有列的名称、数据类型、默认值、空值约束、键约束等信息。例如:
MinChess
2023/04/22
1.7K0
SQL笔记(2)——MySQL的表操作与索引
mysql的information_schema下的COLUMNS表详解
`information_schema.COLUMNS` 表是 MySQL 中的一个元数据表,用于存储数据库中所有表的列信息。这个表对于查询和管理数据库结构非常有用,可以帮助您了解每个表中的列定义、数据类型、约束等细节。
jack.yang
2025/04/05
830
推荐阅读
相关推荐
Server 层混杂信息字典表 | 全方位认识 information_schema(下)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验