zoukankan      html  css  js  c++  java
  • python中的轻量级定时任务调度库:schedule

    提到定时任务调度的时候,相信很多人会想到celery,要么就写个脚本塞到crontab中。不过,一个小的定时脚本,要用celery的话太“重”了。所以,我找到了一个轻量级的定时任务调度的库:schedule。
     任务调度,轻量级的定时任务调度的库:schedule。
    库的安装还是最简单的pip install schedule,使用起来也是很容易理解的。
     
     1 import schedule
     2 import time
     3  
     4 def job():
     5     print("I'm working...")
     6  
     7 schedule.every(10).minutes.do(job)
     8 schedule.every().hour.do(job)
     9 schedule.every().day.at("10:30").do(job)
    10 schedule.every(5).to(10).days.do(job)
    11 schedule.every().monday.do(job)
    12 schedule.every().wednesday.at("13:15").do(job)
    13  
    14 while True:
    15     schedule.run_pending()
    16     time.sleep(1)
    这是在pypi上面给出的示例。这个栗子简单到我不需要怎么解释。而且,通过这个栗子,我们也可以知道,schedule其实就只是个定时器。在while True死循环中,schedule.run_pending()是保持schedule一直运行,去查询上面那一堆的任务,在任务中,就可以设置不同的时间去运行。跟crontab是类似的。
     
    但是,如果是多个任务运行的话,实际上它们是按照顺序从上往下挨个执行的。如果上面的任务比较复杂,会影响到下面任务的运行时间。比如我们这样:
     
     1 import datetime
     2 import schedule
     3 import time
     4  
     5 def job1():
     6     print("I'm working for job1")
     7     time.sleep(2)
     8     print("job1:", datetime.datetime.now())
     9  
    10 def job2():
    11     print("I'm working for job2")
    12     time.sleep(2)
    13     print("job2:", datetime.datetime.now())
    14  
    15 def run():
    16     schedule.every(10).seconds.do(job1)
    17     schedule.every(10).seconds.do(job2)
    18  
    19     while True:
    20         schedule.run_pending()
    21         time.sleep(1)
    接下来你就会发现,两个定时任务并不是10秒运行一次,而是12秒。是的。由于job1和job2本身的执行时间,导致任务延迟了。
     
    其实解决方法也很简单:用多线程/多进程。不要幼稚地问我“python中的多线程不是没有用吗?”这是两码事。开了一条线程,就把job独立出去运行了,不会占主进程的cpu时间,schedule并没有花掉执行一个任务的时间,它的开销只是开启一条线程的时间,所以,下一次执行就变成了10秒后而不是12秒后。
     1 import datetime
     2 import schedule
     3 import threading
     4 import time
     5  
     6 def job1():
     7     print("I'm working for job1")
     8     time.sleep(2)
     9     print("job1:", datetime.datetime.now())
    10  
    11 def job2():
    12     print("I'm working for job2")
    13     time.sleep(2)
    14     print("job2:", datetime.datetime.now())
    15  
    16 def job1_task():
    17     threading.Thread(target=job1).start()
    18  
    19 def job2_task():
    20     threading.Thread(target=job2).start()
    21  
    22 def run():
    23     schedule.every(10).seconds.do(job1_task)
    24     schedule.every(10).seconds.do(job2_task)
    25  
    26     while True:
    27         schedule.run_pending()
    28         time.sleep(1)
    就是这么简单。
     
    唯一要注意的是,这里面job不应当是死循环类型的,也就是说,这个线程应该有一个执行完毕的出口。一是因为线程万一僵死,会是非常棘手的问题;二是下一次定时任务还会开启一个新的线程,执行次数多了就会演变成灾难。如果schedule的时间间隔设置得比job执行的时间短,一样会线程堆积形成灾难,所以,还是需要注意一下的。
     
    schedule这个库使用起来比较简单,内容不是很多。我这里介绍的大概用法基本上够用了,还想了解其他特性的话,可以参考官网:https://schedule.readthedocs.io/en/stable/
     
     
     例子:
     1 import datetime
     2 import schedule
     3 import time
     4  
     5 def job1():
     6     print("I'm working for job1")
     7     time.sleep(2)
     8     print("job1:", datetime.datetime.now())
     9  
    10 def job2():
    11     print("I'm working for job2")
    12     time.sleep(2)
    13     print("job2:", datetime.datetime.now())
    14  
    15 def run():
    16     schedule.every().day.at("22:19").do(job1)
    17     schedule.every().day.at("22:19").do(job2)
    18     #schedule.every(3).seconds.do(job1)
    19     #schedule.every(3).seconds.do(job2)
    20  
    21     while True:
    22         schedule.run_pending()
    23         time.sleep(1)
    24 
    25 
    26 if __name__ == "__main__":
    27 
    28     run()
    多线程例子
     1 import datetime
     2 import schedule
     3 import threading
     4 import time
     5  
     6 def job1():
     7     print("I'm working for job1")
     8     time.sleep(2)
     9     print("job1:", datetime.datetime.now())
    10  
    11 def job2():
    12     print("I'm working for job2")
    13     time.sleep(2)
    14     print("job2:", datetime.datetime.now())
    15  
    16 def job1_task():
    17     threading.Thread(target=job1).start()
    18  
    19 def job2_task():
    20     threading.Thread(target=job2).start()
    21 
    22 
    23 def run():
    24     schedule.every().day.at("22:23").do(job1_task)
    25     schedule.every().day.at("22:23").do(job2_task)
    26     #schedule.every(3).seconds.do(job1_task)
    27     #schedule.every(3).seconds.do(job2_task)
    28  
    29     while True:
    30         schedule.run_pending()
    31         time.sleep(1)
    32 
    33 
    34 if __name__ == "__main__":
    35 
    36     run()
    37  
     
     
     
  • 相关阅读:
    Android 面试题--Activity
    Android 手机卫士--平移动画实现
    Android 手机卫士--导航界面4的业务逻辑
    Android 手机卫士--获取联系人信息并显示与回显
    Android 手机卫士--绑定sim卡序列号
    Android 手机卫士--导航界面3、4和功能列表界面跳转逻辑处理
    Android 手机卫士--导航界面2
    Android 手机卫士--9patch图
    Add Columns to the Web Sessions List
    C# System.Collections.Generic.Dictionary
  • 原文地址:https://www.cnblogs.com/wanglinjie/p/9286338.html
Copyright © 2011-2022 走看看