python中的輕量級定時任務調度庫:schedule

提到定時任務調度的時候,相信不少人會想到 芹菜celery,要麼就寫個腳本塞到crontab中。不過,一個小的定時腳本,要用celery的話太「重」了。因此,我找到了一個輕量級的定時任務調度的庫:schedule。
 
庫的安裝仍是最簡單的pip install schedule,使用起來也是很容易理解的。咱們從最簡單的栗子看起:
 
import schedule
import time
 
def job():
    print("I'm working...")
 
schedule.every(10).minutes.do(job)
schedule.every().hour.do(job)
schedule.every().day.at("10:30").do(job)
schedule.every(5).to(10).days.do(job)
schedule.every().monday.do(job)
schedule.every().wednesday.at("13:15").do(job)
 
while True:
    schedule.run_pending()
    time.sleep(1)

 

這是在pypi上面給出的示例。這個栗子簡單到我不須要怎麼解釋。並且,經過這個栗子,咱們也能夠知道,schedule其實就只是個定時器。在while True死循環中,schedule.run_pending()是保持schedule一直運行,去查詢上面那一堆的任務,在任務中,就能夠設置不一樣的時間去運行。跟crontab是相似的。
 
可是,若是是多個任務運行的話,實際上它們是按照順序從上往下挨個執行的。若是上面的任務比較複雜,會影響到下面任務的運行時間。好比咱們這樣:
 
import datetime
import schedule
import time
 
def job1():
    print("I'm working for job1")
    time.sleep(2)
    print("job1:", datetime.datetime.now())
 
def job2():
    print("I'm working for job2")
    time.sleep(2)
    print("job2:", datetime.datetime.now())
 
def run():
    schedule.every(10).seconds.do(job1)
    schedule.every(10).seconds.do(job2)
 
    while True:
        schedule.run_pending()
        time.sleep(1)

 

接下來你就會發現,兩個定時任務並非10秒運行一次,而是12秒。是的。因爲job1和job2自己的執行時間,致使任務延遲了。
 
其實解決方法也很簡單:用多線程/多進程。不要幼稚地問我「python中的多線程不是沒有用嗎?」這是兩碼事。開了一條線程,就把job獨立出去運行了,不會佔主進程的cpu時間,schedule並無花掉執行一個任務的時間,它的開銷只是開啓一條線程的時間,因此,下一次執行就變成了10秒後而不是12秒後。
 
import datetime
import schedule
import threading
import time
 
def job1():
    print("I'm working for job1")
    time.sleep(2)
    print("job1:", datetime.datetime.now())
 
def job2():
    print("I'm working for job2")
    time.sleep(2)
    print("job2:", datetime.datetime.now())
 
def job1_task():
    threading.Thread(target=job1).start()
 
def job2_task():
    threading.Thread(target=job2).start()
 
def run():
    schedule.every(10).seconds.do(job1_task)
    schedule.every(10).seconds.do(job2_task)
 
    while True:
        schedule.run_pending()
        time.sleep(1)

 

就是這麼簡單。
 
惟一要注意的是,這裏面job不該當是死循環類型的,也就是說,這個線程應該有一個執行完畢的出口。一是由於線程萬一僵死,會是很是棘手的問題;二是下一次定時任務還會開啓一個新的線程,執行次數多了就會演變成災難。若是schedule的時間間隔設置得比job執行的時間短,同樣會線程堆積造成災難,因此,仍是須要注意一下的。
 
schedule這個庫使用起來比較簡單,內容不是不少。我這裏介紹的大概用法基本上夠用了,還想了解其餘特性的話,能夠參考官網: https://schedule.readthedocs.io/en/stable/
 
就醬。
相關文章
相關標籤/搜索