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

人工智能31

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 time

def 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)

即:
APScheduler如何设置任务不并发(即第一个任务执行完再执行下一个)?
可以看到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个不执行。

那这个时候又该怎么办呢?
APScheduler如何设置任务不并发(即第一个任务执行完再执行下一个)?

3.解决方法

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

'''
===========================================
  @author:  jayce
  @file:    apscheduler设置任务不并发.py
  @time:    2022/7/1/001   19:38
===========================================
'''
from apscheduler.executors.pool import ThreadPoolExecutor

if __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)

即:
APScheduler如何设置任务不并发(即第一个任务执行完再执行下一个)?
可以看到,一直在执行第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 time

def exception_maker():
    '''
    异常制造器,用来模拟任务执行被中断
    :return:
    '''
    return 1 / 0

def 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_job
    retval = job.func(*job.args, **job.kwargs)
  File "E:/Code/Python/demo代码/apscheduler设置任务不并发.py", line 14, in exception_maker
    return 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_job
    retval = job.func(*job.args, **job.kwargs)
  File "E:/Code/Python/demo代码/apscheduler设置任务不并发.py", line 14, in exception_maker
    return 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_job
    retval = job.func(*job.args, **job.kwargs)
  File "E:/Code/Python/demo代码/apscheduler设置任务不并发.py", line 14, in exception_maker
    return 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_job
    retval = job.func(*job.args, **job.kwargs)
  File "E:/Code/Python/demo代码/apscheduler设置任务不并发.py", line 14, in exception_maker
    return 1 / 0
ZeroDivisionError: division by zero
job text:每10秒执行一次!

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


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

Original: https://blog.csdn.net/qq_15969343/article/details/125565204
Author: 任博今天就要毕业
Title: APScheduler如何设置任务不并发(即第一个任务执行完再执行下一个)?



相关阅读

Title: (保姆教程)Spyder 配置Tensorflow(2.5.0)和keras(2.4.3)

(保姆教程)Spyder 配置Tensorflow(2.5.0)和keras(2.4.3)

前言

其实安装Tensorflow和keras的过程不难,但是寻找匹配的版本,以及使得Spyder适应花了自己很长时间!

安装Tensorflow

打开anaconda prompt

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

; 首先查看自己的python版本

python --version

接着创建一个新的环境

conda create -n tf python=3.9.7

进入这个环境

conda activate tf

安装Tensorflow

pip install tensorflow==2.5.0

安装Keras

首先输入以下两行代码()

conda install mingw libpython
pip install theano

安装对应的Keras(版本一定要对应)

pip install keras==2.4.3

适应Spyder

在安装完成之后打开Spyder会发现其实用的解释器还是base,这个时候我们需要切换到tf中的python.exe解释器,但是切换之后重启内核,会显示内核错误!

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

解决:

这个时候需要我们先在刚才的命令行中输入

conda install spyder

重新安装spyder,再次打开会发现可以正常运行

输入以下代码测试

import keras
from keras.datasets import mnist
(train_images,train_labels),(test_images,test_labels) = mnist.load_data()
print('shape of train images is ',train_images.shape)
print('shape of train labels is ',train_labels.shape)
print('train labels is ',train_labels)
print('shape of test images is ',test_images.shape)
print('shape of test labels is',test_labels.shape)
print('test labels is',test_labels)

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

成功运行!

但美中不足的是,使用tensorflow之后之前conda自带的很多库就用不了了,需要重新pip或者conda

Original: https://blog.csdn.net/qq_43102225/article/details/124833331
Author: skyoung13
Title: (保姆教程)Spyder 配置Tensorflow(2.5.0)和keras(2.4.3)

相关文章
语音质量评估 人工智能

语音质量评估

MOS(Mean Opnion Score)平均意见得分。 在实时通讯领域,国际电信联盟(ITU)将语音质量的主观评价方法做了标准化处理,代号为ITU-T P.800.1。其中收听质量的绝对等级评分(...
TensorFlow 1.x 2.x教程大集合 人工智能

TensorFlow 1.x 2.x教程大集合

抵扣说明: 1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。 2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。 Original: https://blog.cs...
局域网电话软件系统功能与应用 人工智能

局域网电话软件系统功能与应用

局域网电话在同一介质上集成语音和数据,支持自动呼叫分配、语音邮件和交互式语音响应,以及工作站之间的语音呼叫和电话会议。然而,局域网电话不必仅限于局域网。与数据一样,语音也可以通过广域数据网络传输出去。...
OpenCV-白平衡(灰度世界算法) 人工智能

OpenCV-白平衡(灰度世界算法)

作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 实现原理 白平衡的意义在于,对在特定光源下拍摄时出现的偏色现象,通过加强对应的补色来进行补偿,使...
Canny边缘检测算法及实现 人工智能

Canny边缘检测算法及实现

Canny边缘检测算法及实现 微信公众号: 幼儿园的学霸 目录 文章目录 Canny边缘检测算法及实现 * 目录 前言 原理 步骤 实现 参考资料 前言 提取图片的边缘信息是底层数字图像处理的基本任务...