python四大软件-Python实用模块(二十)Apscheduler

软硬件环境

windows 10 64bits

anaconda with python 3.7

视频看这里

前言

说起定时任务,第一反应应该是windows自带的计划任务或者linux自带的crontab,关于ubuntu操作系统下如何使用crontab可以参考下面这支视频。

安装

安装非常简单, 使用pip

pip install apscheduler

apscheduler的四大组件

triggers 触发器 可以按照日期、时间间隔或者contab表达式三种方式触发

job stores 作业存储器 指定作业存放的位置,默认保存在内存,也可以保存在各种数据库中

executors 执行器 将指定的作业提交到线程池或者进程池中运行

schedulers 作业调度器 常用的有BackgroundScheduler(后台运行)和BlockingScheduler(阻塞式)

代码实践

下面通过几个示例来看看如何来使用apscheduler

import time

from apscheduler.schedulers.background import BlockingScheduler

from apscheduler.triggers.interval import IntervalTrigger

def my_job():

print('my_job, {}'.format(time.ctime()))

if __name__ == "__main__":

scheduler = BlockingScheduler()

# 间隔设置为1秒,还可以使用minutes、hours、days、weeks等

intervalTrigger=IntervalTrigger(seconds=1)

# 给作业设个id,方便作业的后续操作,暂停、取消等

scheduler.add_job(my_job, intervalTrigger, id='my_job_id')

scheduler.start()

print('=== end. ===')

执行代码,输出是这样的

da0428b99dcbac16.png

因为我们使用了BlockingScheduler,它是阻塞式的,所以只看到了my_job方法中的输出,而语句print('=== end. ===')并没有被执行。BackgroundScheduler它可以在后台运行,不会阻塞主线程的执行,来看下面的代码

import time

from apscheduler.schedulers.background import BackgroundScheduler

from apscheduler.triggers.interval import IntervalTrigger

def my_job():

print('my_job, {}'.format(time.ctime()))

if __name__ == "__main__":

scheduler = BackgroundScheduler()

intervalTrigger=IntervalTrigger(seconds=1)

scheduler.add_job(my_job, intervalTrigger, id='my_job_id')

scheduler.start()

print('=== end. ===')

while True:

time.sleep(1)

代码执行的结果是这样的

b7b12e82dfb30c21.png

如果把triggers设置成DateTrigger,就变成作业在某一个时间点执行,示例如下

import time

import datetime

from apscheduler.schedulers.background import BlockingScheduler

from apscheduler.triggers.date import DateTrigger

def my_job():

print('my_job, {}'.format(time.ctime()))

if __name__ == "__main__":

scheduler = BlockingScheduler()

intervalTrigger=DateTrigger(run_date='2020-07-17 16:18:55')

scheduler.add_job(my_job, intervalTrigger, id='my_job_id')

scheduler.start()

等到设定的时间到了,作业就会被自行一次

fb4485246501d6e7.png

如果想按照指定的周期去执行的话,就需要使用CronTrigger了,工作原理跟UNIX中crontab定时任务非常相似,它可以指定非常详细且复杂的规则。同样的来看示例代码

import time

from apscheduler.schedulers.background import BlockingScheduler

from apscheduler.triggers.cron import CronTrigger

def my_job():

print('my_job, {}'.format(time.ctime()))

if __name__ == "__main__":

scheduler = BlockingScheduler()

# 第一秒执行作业

intervalTrigger=CronTrigger(second=1)

# 每天的19:30:01执行作业

# intervalTrigger=CronTrigger(hour=19, minute=30, second=1)

# 每年的10月1日19点执行作业

# intervalTrigger=CronTrigger(month=10, day=1, hour=19)

scheduler.add_job(my_job, intervalTrigger, id='my_job_id')

scheduler.start()

代码执行的效果是这样的

1eeecaf373780dc3.png

上面的代码中并没有使用executors,因为只有一个作业,但是从调试中可以发现,默认情况下,apscheduler也是使用了ThreadPoolExecutor,且线程池的大小是10

b7ced9fbb654e9a1.png

下面我们看看executors的使用

import time

from apscheduler.schedulers.background import BlockingScheduler

from apscheduler.triggers.interval import IntervalTrigger

from apscheduler.executors.pool import ThreadPoolExecutor

def my_job():

print('my_job, {}'.format(time.ctime()))

if __name__ == "__main__":

executors = {

'default': ThreadPoolExecutor(20)

}

scheduler = BlockingScheduler(executors=executors)

intervalTrigger=IntervalTrigger(seconds=1)

scheduler.add_job(my_job, intervalTrigger, id='my_job_id')

scheduler.start()

可以看到,我们将线程池的大小改为了20,在初始化scheduler的时候将executors传递进去,后面的操作就跟之前的完全一样了

0c0bbcc604a587b5.png

关于ThreadPoolExecutor和ProcessPoolExecutor的选择问题,这里有一个原则,如果是cpu密集型的作业,使用ProcessPoolExecutor,其它的使用ThreadPoolExecutor,当然ThreadPoolExecutor和ProcessPoolExecutor也是可以混用的

最后我们来看看作业存储器,我们把它改成存储到sqlite中

import time

from apscheduler.schedulers.background import BlockingScheduler

from apscheduler.triggers.interval import IntervalTrigger

from apscheduler.executors.pool import ThreadPoolExecutor

from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore

def my_job():

print('my_job, {}'.format(time.ctime()))

jobstores = {

'default': SQLAlchemyJobStore(url='sqlite:///jobs.sqlite')

}

if __name__ == "__main__":

executors = {

'default': ThreadPoolExecutor(20)

}

scheduler = BlockingScheduler(jobstores=jobstores, executors=executors)

intervalTrigger=IntervalTrigger(seconds=1)

scheduler.add_job(my_job, intervalTrigger, id='my_job_id')

scheduler.start()

代码执行后,会在源码目录下生成sqlite数据库文件jobs.sqlite,我们使用图形化工具打开查看,可以看到数据库中存放的作业的id和作业下次执行的时间

fc7a00dd960a2bf5.png

参考资料

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值