APScheduler如何设置任务不并发(即第一个任务执行完再执行下一个)?

  • 1.软件环境
  • 2.问题描述
  • 3.解决方法
  • 4.结果预览
  • FAQ
    • 1.`APScheduler`如果某个任务挂掉了,整个定时任务程序会中断吗?还是下次时间继续执行该任务?

1.软件环境

Windows10 教育版64位
Python 3.6.3
APScheduler 3.6.3

2.问题描述

Python中定时任务的解决方案,总体来说有四种,分别是:crontabschedulerCeleryAPScheduler,其中:

  1. crontabLinux 的一个定时任务管理工具,在Windows上面有替代品pycron,但Windows不像 Linux那样有很多强大的命令程序,pycron使用起来有局限性定制性不好;
  2. Scheduler太过于简单、复杂一点的定时任务做起来太困难,特别是以月份以上时间单位的定时任务;
  3. Celery依赖的软件比较多,比较耗资源;
  4. APScheduler(Advanced Python Scheduler) 基于 Quartz,可以跨平台而且配置方便,提供了dateintervalcron3种不同的触发器,与Linux上原生的 crontab 格式兼容,可以设置任何高度复杂的定时任务,灵活的要死。

在此不介绍APScheduler的基本特性,有需要的可以直接去看APScheduler官方文档,我们直接切到主题:

APScheduler如何设置任务不并发(即第一个任务执行完再执行下一个)?

APScheduler在多个任务相同时间点同时被触发时,会同时并发执行多个任务,如使用下方的示例代码:

'''
===========================================@author:  jayce@file:    apscheduler设置任务不并发.py         @time:    2022/7/1/001   19:38
===========================================
'''
from apscheduler.schedulers.blocking import BlockingScheduler
import timedef job_printer(text):'''死循环,用来模拟长时间执行的任务:param text: :return: '''while True:time.sleep(2)print("job text:{}".format(text))if __name__ == '__main__':schedule = BlockingScheduler()schedule.add_job(job_printer, "cron", second='*/10', args=['每10秒执行一次!'])schedule.add_job(job_printer, "cron", second='*/20', args=['每20秒执行一次!'])schedule.print_jobs()schedule.start()

可以看到,函数job_printer是一个死循环,用来模拟长时间执行的任务,我们使用add_jobAPScheduler中添加2个job_printer,区别是2个任务的时间间隔为:每10秒执行一次每20秒执行一次
因为job_printer是一个死循环,相当于job_printer一直没有被执行完,但其实APScheduler在任务没有被执行完的情况下,同时执行多个不同的job_printer

job text:每10秒执行一次!
job text:每20秒执行一次!
job text:每10秒执行一次!
job text:每20秒执行一次!
job text:每10秒执行一次!
job text:每20秒执行一次!
job text:每10秒执行一次!
job text:每20秒执行一次!
job text:每10秒执行一次!
Execution of job "job_printer (trigger: cron[second='*/10'], next run at: 2022-07-01 20:47:50 CST)" skipped: maximum number of running instances reached (1)

即:

可以看到10秒的job_printer和20秒的job_printer交替被执行,而其实10秒的job_printer其实根本没有执行完。这在CPU或者GPU等硬件设备能够承担负载的情况下,当然是好事,但如果你的硬件不够的话,发生OOM等资源不够的情况,程序就被中断了,导致你的模型训练或业务逻辑失败!
具体的
我这边是使用APSchedulerTensorflow进行在线学习(online learning)时,在不同的时间节点下会对模型使用不一样的重训练方式,如有2个定时任务(A:每10秒执行一次,B:每20秒执行一次)和2种重训练方式(XY),当你的显存存在如下情况:

显存很少只够一个程序进行训练,不能多个程序同时运行,否则会OOM

那么只能引导程序依次执行,而不能并发执行,等当同一时间内XY同时被触发时,只执行其中1个,另外1个不执行。

那这个时候又该怎么办呢?

3.解决方法

通过查阅官方文档,发现可以通过设置执行任务的线程数,来控制只有1个执行器进行任务的执行,进而达到执行完任务X再执行任务Y,具体如下:

'''
===========================================@author:  jayce@file:    apscheduler设置任务不并发.py         @time:    2022/7/1/001   19:38
===========================================
'''
from apscheduler.executors.pool import ThreadPoolExecutorif __name__ == '__main__':# 为了防止全量和增量并发造成显存溢出,进而训练失败,设置同一时间只能有一个任务运行schedule = BlockingScheduler(executors={'default': ThreadPoolExecutor(1)})

通过向BlockingScheduler设定最大的ThreadPoolExecutor=1,即可达到我们想要的效果!

4.结果预览

job text:每10秒执行一次!
job text:每10秒执行一次!
job text:每10秒执行一次!
job text:每10秒执行一次!
job text:每10秒执行一次!
Execution of job "job_printer (trigger: cron[second='*/10'], next run at: 2022-07-01 21:17:50 CST)" skipped: maximum number of running instances reached (1)
job text:每10秒执行一次!
job text:每10秒执行一次!
job text:每10秒执行一次!
job text:每10秒执行一次!
job text:每10秒执行一次!
Execution of job "job_printer (trigger: cron[second='*/10'], next run at: 2022-07-01 21:18:00 CST)" skipped: maximum number of running instances reached (1)
Execution of job "job_printer (trigger: cron[second='*/20'], next run at: 2022-07-01 21:18:00 CST)" skipped: maximum number of running instances reached (1)

即:

可以看到,一直在执行第1个被触发的任务,相同时间被触发的任务都被skipped了~~
当然,如果你想要第1个任务执行完时,执行被跳过的任务,可以通过在add_job中设置misfire_grace_time实现!

FAQ

1.APScheduler如果某个任务挂掉了,整个定时任务程序会中断吗?还是下次时间继续执行该任务?

答案是:程序不会中断,到下次执行任务的时间点,还会重新执行。
具体的,使用如下测试代码:

'''
===========================================@author:  jayce@file:    apscheduler设置任务不并发.py         @time:    2022/7/1/001   19:38
===========================================
'''
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.executors.pool import ThreadPoolExecutor
import timedef exception_maker():'''异常制造器,用来模拟任务执行被中断:return:'''return 1 / 0def job_printer(text):'''死循环,用来模拟长时间执行的任务:param text::return:'''while True:time.sleep(2)print("job text:{}".format(text))if __name__ == '__main__':schedule = BlockingScheduler()schedule.add_job(job_printer, "cron", second='*/10', args=['每10秒执行一次!'])schedule.add_job(exception_maker, "cron", second='*/5')schedule.print_jobs()schedule.start()

可以看到exception_maker已经失败多次,但是不影响其他任务和它自身的下次执行:

Job "exception_maker (trigger: cron[second='*/5'], next run at: 2022-07-01 19:53:30 CST)" raised an exception
Traceback (most recent call last):File "C:\Users\Jayce\Anaconda3\envs\tf2.3\lib\site-packages\apscheduler\executors\base.py", line 125, in run_jobretval = job.func(*job.args, **job.kwargs)File "E:/Code/Python/demo代码/apscheduler设置任务不并发.py", line 14, in exception_makerreturn 1 / 0
ZeroDivisionError: division by zero
Job "exception_maker (trigger: cron[second='*/5'], next run at: 2022-07-01 19:53:35 CST)" raised an exception
Traceback (most recent call last):File "C:\Users\Jayce\Anaconda3\envs\tf2.3\lib\site-packages\apscheduler\executors\base.py", line 125, in run_jobretval = job.func(*job.args, **job.kwargs)File "E:/Code/Python/demo代码/apscheduler设置任务不并发.py", line 14, in exception_makerreturn 1 / 0
ZeroDivisionError: division by zero
job text:每10秒执行一次!
job text:每10秒执行一次!
Job "exception_maker (trigger: cron[second='*/5'], next run at: 2022-07-01 19:53:40 CST)" raised an exception
Traceback (most recent call last):File "C:\Users\Jayce\Anaconda3\envs\tf2.3\lib\site-packages\apscheduler\executors\base.py", line 125, in run_jobretval = job.func(*job.args, **job.kwargs)File "E:/Code/Python/demo代码/apscheduler设置任务不并发.py", line 14, in exception_makerreturn 1 / 0
ZeroDivisionError: division by zero
job text:每10秒执行一次!
job text:每10秒执行一次!
Execution of job "job_printer (trigger: cron[second='*/10'], next run at: 2022-07-01 19:53:40 CST)" skipped: maximum number of running instances reached (1)
Job "exception_maker (trigger: cron[second='*/5'], next run at: 2022-07-01 19:53:45 CST)" raised an exception
Traceback (most recent call last):File "C:\Users\Jayce\Anaconda3\envs\tf2.3\lib\site-packages\apscheduler\executors\base.py", line 125, in run_jobretval = job.func(*job.args, **job.kwargs)File "E:/Code/Python/demo代码/apscheduler设置任务不并发.py", line 14, in exception_makerreturn 1 / 0
ZeroDivisionError: division by zero
job text:每10秒执行一次!

即:


都看到这里了,还不赶紧点赞评论收藏走一波?

APScheduler如何设置任务不并发(即第一个任务执行完再执行下一个)?相关推荐

  1. JUC并发编程 第一季

    1.JUC java.util.concurrent 并发编程工具类 java.util.concurrent java.util.concurrent.atomic java.util.concur ...

  2. 【网络】高性能网络编程--下一个10年,是时候考虑C10M并发问题了

    转载:http://www.52im.net/thread-568-1-1.html 1.前言 在本系列文章的上篇中我们回顾了过云的10年里,高性能网络编程领域著名的C10K问题及其成功的解决方案(上 ...

  3. 高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了

    1.前言 在本系列文章的上篇中我们回顾了过云的10年里,高性能网络编程领域著名的C10K问题及其成功的解决方案(上篇请见:<高性能网络编程(二):上一个10年,著名的C10K并发连接问题> ...

  4. java并发编程第一课 线程的创建、停止和状态变更

    开篇词: 由点及面,搭建你的 Java 并发知识网 你好,欢迎学习<Java 并发编程核心 78 讲>,我是讲师星星,一线互联网公司资深研发工程师,参与过集团内多个重点项目的设计与开发. ...

  5. 如何进bios设置ssd固态硬盘为第一启动

    对于一些小伙伴来说,安装了双硬盘,但是却不懂如何进bios设置ssd固态硬盘为第一启动,没能将资源进行合理利用.今天快启动小编带大家了解进bios设置ssd固态硬盘为第一启动的相关操作,不懂的小伙伴一 ...

  6. [安装之1] dell设置从ssd启动_如何进bios设置ssd固态硬盘为第一启动

    对于一些小伙伴来说,安装了双硬盘,但是却不懂如何进bios设置ssd固态硬盘为第一启动,没能将资源进行合理利用.今天快启动小编带大家了解进bios设置ssd固态硬盘为第一启动的相关操作,不懂的小伙伴一 ...

  7. Win10便签设置日历的一周第一天为周日的方法

    Win10系统电脑上带有日历功能的云便签工具不仅可以打开日历以月视图的形式查看提醒.新增.修改.删除或完成的便签内容,还能设置日历的一周第一天显示为周六.周日或周一.下面就介绍一下这款Win10便签设 ...

  8. dell设置从ssd启动_如何进bios设置ssd固态硬盘为第一启动

    对于一些小伙伴来说,安装了双硬盘,但是却不懂如何进bios设置ssd固态硬盘为第一启动,没能将资源进行合理利用.今天快启动小编带大家了解进bios设置ssd固态硬盘为第一启动的相关操作,不懂的小伙伴一 ...

  9. 重装系统如何设置u盘启动为第一启动项

    如何设置u盘启动为第一启动项呢?将U盘设为第一启动项,是使用U盘装机工具重装系统的重要步骤之一,很多网友不清楚怎么操作,下面小编就分享下设置u盘启动为第一启动项的方法. 工具/原料: 系统版本:win ...

最新文章

  1. JSP+Servlet+JavaBean
  2. 【直播回顾】云栖社区特邀专家徐雷Java Spring Boot开发实战系列课程(第19讲):Java Spring Cloud微服务架构模式与开发实战...
  3. 基于Pyspark和Thunder的神经图像数据分析-实验运行结果
  4. 手把手教你写Linux I2C设备驱动
  5. python中的__new__和__init__
  6. java pdf stamper_PDFStamper在几个PDF文件上失败(itext 5.5.1)
  7. 数学之美!这些美轮美奂的数学动图
  8. PHP服务器端语言是什么意思,PHP作为服务器端语言,有哪些优点?
  9. git冲突解决办法合集
  10. redis 分布式锁流程图
  11. ansible-playbook之循环(Loops)
  12. http 和 https 区别?
  13. 浅析希区柯克的悬念电影:以《惊魂记》为例
  14. 工具 | Axure基础操作 No.6
  15. Python做下载器需要掌握哪些
  16. 查看oracle建表语句
  17. 教务管理系统数据字典mysql_数据库大作业_-教务管理系统
  18. IDEA提示“Spring Configuration Check“ “Unmapped Spring configuration files found.“
  19. 数据不平衡分类问题 代价矩阵 损失函数
  20. [转]关于uboot的main_loop

热门文章

  1. python解二元一次方程组
  2. 史上最全各类面试题汇总,没有之一,不接受反驳
  3. android数据线接口定义,安卓手机数据线接口类型
  4. [附源码]SSM计算机毕业设计逸尘房屋销售管理系统JAVA
  5. vue的多标签页实现
  6. java图形验证码去除干扰,使用python 对验证码图片进行降噪处理
  7. 数据库 SQL 语句学习
  8. 使用OneDNS完美解决办公网络优化问题
  9. 嵩山少林寺网站向全世界公布了千年武功秘籍
  10. Web前端之jQuery 一