您好,登錄后才能下訂單哦!
這篇文章主要講解了“APScheduler怎么設(shè)置任務(wù)不并發(fā)”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“APScheduler怎么設(shè)置任務(wù)不并發(fā)”吧!
Windows10 教育版64位
Python 3.6.3
APScheduler 3.6.3
Python
中定時任務(wù)的解決方案,總體來說有四種,分別是:crontab
、 scheduler
、 Celery
、APScheduler
,其中:
crontab是 Linux 的一個定時任務(wù)管理工具,在Windows上面有替代品pycron,但Windows不像 Linux那樣有很多強(qiáng)大的命令程序,pycron使用起來有局限性,定制性不好;
Scheduler太過于簡單、復(fù)雜一點(diǎn)的定時任務(wù)做起來太困難,特別是以月份以上時間單位的定時任務(wù);
Celery依賴的軟件比較多,比較耗資源;
APScheduler(Advanced Python Scheduler) 基于 Quartz,可以跨平臺而且配置方便,提供了date、interval、cron3種不同的觸發(fā)器,與Linux上原生的 crontab 格式兼容,可以設(shè)置任何高度復(fù)雜的定時任務(wù),靈活的要死。
在此不介紹APScheduler
的基本特性,有需要的可以直接去看APScheduler官方文檔,我們直接切到主題:
APScheduler如何設(shè)置任務(wù)不并發(fā)(即第一個任務(wù)執(zhí)行完再執(zhí)行下一個)?
APScheduler
在多個任務(wù)相同時間點(diǎn)同時被觸發(fā)時,會同時并發(fā)執(zhí)行多個任務(wù),如使用下方的示例代碼:
''' =========================================== @author: jayce @file: apscheduler設(shè)置任務(wù)不并發(fā).py @time: 2022/7/1/001 19:38 =========================================== ''' from apscheduler.schedulers.blocking import BlockingScheduler import time def job_printer(text): ''' 死循環(huán),用來模擬長時間執(zhí)行的任務(wù) :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秒執(zhí)行一次!']) schedule.add_job(job_printer, "cron", second='*/20', args=['每20秒執(zhí)行一次!']) schedule.print_jobs() schedule.start()
可以看到,函數(shù)job_printer
是一個死循環(huán),用來模擬長時間執(zhí)行的任務(wù),我們使用add_job
向APScheduler
中添加2個job_printer
,區(qū)別是2個任務(wù)的時間間隔為:每10秒執(zhí)行一次
和每20秒執(zhí)行一次
。
因?yàn)?code>job_printer是一個死循環(huán),相當(dāng)于job_printer
一直沒有被執(zhí)行完,但其實(shí)APScheduler
在任務(wù)沒有被執(zhí)行完的情況下,同時執(zhí)行多個不同的job_printer
:
job text:每10秒執(zhí)行一次!
job text:每20秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
job text:每20秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
job text:每20秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
job text:每20秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
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
交替被執(zhí)行,而其實(shí)10秒的job_printer
其實(shí)根本沒有執(zhí)行完。這在CPU
或者GPU
等硬件設(shè)備能夠承擔(dān)負(fù)載的情況下,當(dāng)然是好事,但如果你的硬件不夠的話,發(fā)生OOM等資源不夠的情況,程序就被中斷了,導(dǎo)致你的模型訓(xùn)練或業(yè)務(wù)邏輯失?。?br/>具體的
:
我這邊是使用APScheduler
和Tensorflow
進(jìn)行在線學(xué)習(xí)(online learning
)時,在不同的時間節(jié)點(diǎn)下會對模型使用不一樣的重訓(xùn)練方式,如有2個定時任務(wù)(A
:每10
秒執(zhí)行一次,B
:每20
秒執(zhí)行一次)和2種重訓(xùn)練方式(X
和Y
),當(dāng)你的顯存存在如下情況:
顯存很少只夠一個程序進(jìn)行訓(xùn)練,不能多個程序同時運(yùn)行,否則會
OOM
;
那么只能引導(dǎo)程序依次執(zhí)行,而不能并發(fā)執(zhí)行,等當(dāng)同一時間內(nèi)X
和Y
同時被觸發(fā)時,只執(zhí)行其中1個,另外1個不執(zhí)行。
那這個時候又該怎么辦呢
通過查閱官方文檔,發(fā)現(xiàn)可以通過設(shè)置執(zhí)行任務(wù)的線程數(shù),來控制只有1個執(zhí)行器進(jìn)行任務(wù)的執(zhí)行,進(jìn)而達(dá)到執(zhí)行完任務(wù)X
再執(zhí)行任務(wù)Y
,具體如下:
''' =========================================== @author: jayce @file: apscheduler設(shè)置任務(wù)不并發(fā).py @time: 2022/7/1/001 19:38 =========================================== ''' from apscheduler.executors.pool import ThreadPoolExecutor if __name__ == '__main__': # 為了防止全量和增量并發(fā)造成顯存溢出,進(jìn)而訓(xùn)練失敗,設(shè)置同一時間只能有一個任務(wù)運(yùn)行 schedule = BlockingScheduler(executors={'default': ThreadPoolExecutor(1)})
通過向BlockingScheduler
設(shè)定最大的ThreadPoolExecutor=1
,即可達(dá)到我們想要的效果!
job text:每10秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
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秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
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)
即:
可以看到,一直在執(zhí)行第1個被觸發(fā)的任務(wù),相同時間被觸發(fā)的任務(wù)都被skipped
了~~
當(dāng)然,如果你想要第1個任務(wù)執(zhí)行完時,執(zhí)行被跳過的任務(wù),可以通過在add_job
中設(shè)置misfire_grace_time
實(shí)現(xiàn)!
1.APScheduler
如果某個任務(wù)掛掉了,整個定時任務(wù)程序會中斷嗎?還是下次時間繼續(xù)執(zhí)行該任務(wù)?
答案是:程序不會中斷,到下次執(zhí)行任務(wù)的時間點(diǎn),還會重新執(zhí)行。
具體的,使用如下測試代碼:
''' =========================================== @author: jayce @file: apscheduler設(shè)置任務(wù)不并發(fā).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(): ''' 異常制造器,用來模擬任務(wù)執(zhí)行被中斷 :return: ''' return 1 / 0 def job_printer(text): ''' 死循環(huán),用來模擬長時間執(zhí)行的任務(wù) :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秒執(zhí)行一次!']) schedule.add_job(exception_maker, "cron", second='*/5') schedule.print_jobs() schedule.start()
可以看到exception_maker
已經(jīng)失敗多次,但是不影響其他任務(wù)和它自身的下次執(zhí)行:
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設(shè)置任務(wù)不并發(fā).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設(shè)置任務(wù)不并發(fā).py", line 14, in exception_maker
return 1 / 0
ZeroDivisionError: division by zero
job text:每10秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
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設(shè)置任務(wù)不并發(fā).py", line 14, in exception_maker
return 1 / 0
ZeroDivisionError: division by zero
job text:每10秒執(zhí)行一次!
job text:每10秒執(zhí)行一次!
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設(shè)置任務(wù)不并發(fā).py", line 14, in exception_maker
return 1 / 0
ZeroDivisionError: division by zero
job text:每10秒執(zhí)行一次!
即:
感謝各位的閱讀,以上就是“APScheduler怎么設(shè)置任務(wù)不并發(fā)”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對APScheduler怎么設(shè)置任務(wù)不并發(fā)這一問題有了更深刻的體會,具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。