目录
1.软件环境2.问题描述3.解决方法4.结果预览FAQ1.软件环境
Windows10 教育版64位
Python 3.6.3
APScheduler 3.6.3
2.问题描述
Python
中定时任务的解决方案,总体来说有四种,分别是:crontab
、 scheduler
、 Celery
、APScheduler
,其中:
在此不介绍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_job
向APScheduler
中添加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等资源不够的情况,程序就被中断了,导致你的模型训练或业务逻辑失败!具体的
:
我这边是使用APScheduler
和Tensorflow
进行在线学习(online learning
)时,在不同的时间节点下会对模型使用不一样的重训练方式,如有2个定时任务(A
:每10
秒执行一次,B
:每20
秒执行一次)和2种重训练方式(X
和Y
),当你的显存存在如下情况:
显存很少只够一个程序进行训练,不能多个程序同时运行,否则会
OOM
;
那么只能引导程序依次执行,而不能并发执行,等当同一时间内X
和Y
同时被触发时,只执行其中1个,另外1个不执行。
那这个时候又该怎么办呢
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)
即:
可以看到,一直在执行第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如何设置任务不并发的文章就介绍到这了,更多相关APScheduler 任务不并发内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
X 关闭
X 关闭
- 1转转集团发布2022年二季度手机行情报告:二手市场“飘香”
- 2充电宝100Wh等于多少毫安?铁路旅客禁止、限制携带和托运物品目录
- 3好消息!京东与腾讯续签三年战略合作协议 加强技术创新与供应链服务
- 4名创优品拟通过香港IPO全球发售4100万股 全球发售所得款项有什么用处?
- 5亚马逊云科技成立量子网络中心致力解决量子计算领域的挑战
- 6京东绿色建材线上平台上线 新增用户70%来自下沉市场
- 7网红淘品牌“七格格”chuu在北京又开一家店 潮人新宠chuu能红多久
- 8市场竞争加剧,有车企因经营不善出现破产、退网、退市
- 9北京市市场监管局为企业纾困减负保护经济韧性
- 10市场监管总局发布限制商品过度包装标准和第1号修改单