2022年 11月 3日

Python实现定时任务的几种方法

  1. """
  2. Python实现定时任务的4种方法:
  3. 1、死循环 + time.sleep()
  4. 2、利用Timer对象实现定时输出
  5. 3、sched 事件调度器
  6. 4、APScheduler
  7. """
  8. import datetime as dt
  9. import time
  10. # 1、死循环 + time.sleep()实现定时,不过最后陷入死循环
  11. def task(s):
  12. while True:
  13. print(dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
  14. time.sleep(s)
  15. # task(2)
  16. # 2、class threading.Timer(interval, function, args=[], kwargs={}) interval 是时间间隔,function 是可调用的对象,args 和 kwargs 会作为 function 的参数。
  17. from threading import Timer
  18. def func(): # 需要定时执行的函数
  19. print([dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S")])
  20. def task(s):
  21. print(dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
  22. Timer(s, func, ()).start()
  23. # task(2)
  24. ## 实现循环打印的方法一:在function里面继续注册一个Timer,这样就能在下一个interval继续执行function
  25. def hello():
  26. print('hello world')
  27. Timer(10.0,hello).start() # 有一点类似于函数的递归调用,即我调用我自己
  28. # t = Timer(10.0, hello) #10秒以后运行hello()函数,但是只能运行一次
  29. # t.start()
  30. ## 实现循环打印的方法二:
  31. # 以后再做补充
  32. # 3、sched 事件调度器
  33. """
  34. (1) 构造一个sched.scheduler类
  35. scheduler = sched.scheduler(timefunc, delayfunc)
  36. timefunc:当前时间(默认 time.time)
  37. delayfunc:暂停运行的时间单元(默认 time.sleep)
  38. (2) 添加调度任务
  39. ① 定点:延长指定的时间执行任务
  40. scheduler.enter(delay, priority, action, argument=(), kwargs={})
  41. delay:延迟多长时间执行任务(单位:秒)
  42. priority:优先级:越小优先级越大
  43. action:函数名称
  44. argument 和 kwargs:函数位置和关键字参数
  45. ② 定时:指定 time 时刻执行任务
  46. scheduler.enterabs(time, priority, action, argument=(), kwargs={}):
  47. time:指定时间点
  48. 其余参数同上
  49. (3) 运行任务
  50. scheduler.run()
  51. """
  52. def func1():
  53. print("scheduler1")
  54. def func2():
  55. print("scheduler2")
  56. import sched
  57. def task(s):
  58. print(dt.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
  59. # 初始化 sched 模块的 scheduler 类
  60. scheduler1 = sched.scheduler(time.time, time.sleep)
  61. scheduler2 = sched.scheduler(time.time, time.sleep)
  62. # 增加调度任务
  63. scheduler1.enter(s, 2, func1,())
  64. scheduler2.enter(s,1,func2,())
  65. # 运行任务
  66. scheduler1.run()
  67. scheduler2.run()
  68. # task(2)
  69. # 4、APScheduler
  70. """
  71. APScheduler 四个组件分别为:调度器(scheduler)、触发器(trigger),作业存储(job store),执行器(executor)
  72. (1)新建调度器schedulers
  73. BlockingScheduler:调度器在当前进程的主线程中运行,也就是会阻塞当前线程
  74. BackgroundScheduler:调度器在后台线程中运行,不会阻塞当前线程
  75. (2)添加调度任务trigger
  76. ① date 触发器:(指定时间点触发),参数如下:
  77. run_date(datetime或str):任务运行的日期或时间
  78. timezone(datetime.tzinfo或str):指定时区
  79. # 例1:在 2020-9-24 时刻运行一次 func 方法
  80. scheduler.add_job(func, 'date', run_date = dt.date(2020, 9, 24))
  81. # 例2: 在 2020-9-24 15:10:00 时刻运行一次 func 方法
  82. scheduler.add_job(func, 'date', run_date = dt.datetime(2020, 9, 24, 15, 10, 0))
  83. # 例3: 在 2020-9-24 15:11:00 时刻运行一次 func 方法
  84. scheduler.add_job(func, 'date', run_date = '2020-9-24 15:11:00')
  85. ② interval 触发器: (固定时间间隔触发),参数如下:
  86. weeks(int):间隔几周
  87. days(int):间隔几天
  88. hours(int):间隔几小时
  89. minutes(int):间隔几分钟
  90. seconds(int):间隔几秒钟
  91. start_date(datetime或str):开始时间
  92. end_date(datetime或str):结束时间
  93. timezone(datetime.tzinfo或str):时区
  94. # 例1:每隔两分钟执行一次 func 方法
  95. scheduler.add_job(func, 'interval', minutes = 2)
  96. # 例2:在 2020-9-24 15:15:00 ~ 2020-9-24 15:20:00 之间, 每隔两分钟执行一次 func 方法
  97. scheduler.add_job(func, 'interval', minutes = 2, start_date = '2020-9-24 15:15:00' , end_date = '2020-9-24 15:20:00')
  98. ③ cron 触发器:(在指定时间周期性地触发),参数如下:
  99. year(int 或 str):年
  100. month(int 或 str):月
  101. day(int 或 str):日
  102. week(int 或 str):周(1-53)
  103. day_of_week(int 或 str):星期几(0-6)
  104. hour(int 或 str):时
  105. minute(int 或 str):分
  106. second(int 或 str):秒
  107. start_date(datetime或str):最早开始时间(包含)
  108. end_date(datetime或str):最晚结束时间(包含)
  109. timezone(datetime.tzinfo或str):指定时区
  110. # 例:在每年 1-3、7-9 月份中的每个星期一、二中的 00:00, 01:00, 02:00 和 03:00 执行 func 任务
  111. scheduler.add_job(func, 'cron', month = '1-3,7-9',day='0, tue', hour='0-3')
  112. (3)管理调度任务job stores
  113. ① 添加job:
  114. # add_job():可以改变或者移除 job
  115. scheduler.add_job(func, 'interval', minutes = 2)
  116. # scheduled_job():只适用于应用运行期间不会改变的 job
  117. scheduler.scheduled_job(func, 'interval', minutes = 2)
  118. ② 移除job:
  119. # remove_job() :根据 job 的 id 来移除,所以要在 job 创建的时候指定一个 id
  120. scheduler.add_job(func, 'interval', minutes = 2, id = 'job_one')
  121. scheduler.remove_job(job_one)
  122. # job.remove() :对 job 执行 remove 方法
  123. job = add_job(func, 'interval', minutes = 2, id = 'job_one')
  124. job.remvoe()
  125. ③ 暂停job:
  126. apscheduler.job.Job.pause()
  127. apscheduler.schedulers.base.BaseScheduler.pause_job()
  128. ④ 恢复job:
  129. apscheduler.job.Job.resume()
  130. apscheduler.schedulers.base.BaseScheduler.resume_job()
  131. ⑤ 修改job:
  132. # modify_job()
  133. scheduler.modify_job('job_one', minutes = 5)
  134. # job.modify()
  135. job = scheduler.add_job(func, 'interval', minutes = 2)
  136. job.modify(minutes = 5)
  137. ⑥ 关闭job:
  138. scheduler.shutdown()
  139. scheduler.shutdown(wait=false)
  140. (4)executors:执行调度任务的模块,常用的 executor 有两种:
  141. ProcessPoolExecutor
  142. ThreadPoolExecutor
  143. (5)运行调度任务
  144. scheduler.start()
  145. """