You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python实现任务固定间隔精准调度(非任务结束后计时)

实现schedule库的固定间隔调度(从任务启动时间计时)

默认情况下,schedule库的定时任务采用延迟调度:任务执行完成后才会计算下一次的触发时间,这就导致如果任务执行耗时超过设定间隔,下一次任务会被延后。要实现从任务启动时间开始计时的固定间隔调度,可以通过异步执行任务的方式解决,让调度逻辑不受任务执行阻塞的影响。

解决方案1:使用线程异步执行任务

将任务放到独立线程中运行,这样主调度循环不会被任务执行阻塞,仍能按设定的固定间隔触发下一次任务:

import schedule
import time
import threading

def job():
    print("Process triggered at:", time.strftime("%Y-%m-%d %H:%M:%S"))
    time.sleep(30)
    print("Process ended at:", time.strftime("%Y-%m-%d %H:%M:%S"))

# 包装任务为线程执行
def run_job_async():
    threading.Thread(target=job).start()

frequency_seconds = 60
# 调度异步任务
schedule.every(frequency_seconds).seconds.do(run_job_async)

while True:
    schedule.run_pending()
    time.sleep(1)

解决方案2:避免任务重叠(可选)

如果不希望多个任务实例同时运行,可以添加线程锁,让后续任务等待前一个任务完成后再执行,但调度间隔仍保持从启动时间计算:

import schedule
import time
import threading

# 创建线程锁
job_lock = threading.Lock()

def job():
    with job_lock:
        print("Process triggered at:", time.strftime("%Y-%m-%d %H:%M:%S"))
        time.sleep(30)
        print("Process ended at:", time.strftime("%Y-%m-%d %H:%M:%S"))

def run_job_async():
    threading.Thread(target=job).start()

frequency_seconds = 60
schedule.every(frequency_seconds).seconds.do(run_job_async)

while True:
    schedule.run_pending()
    time.sleep(1)

效果验证

使用上述代码后,输出会符合预期:

Process triggered at: 2024-03-25 06:57:23
Process ended at: 2024-03-25 06:57:53
Process triggered at: 2024-03-25 06:58:23
Process ended at: 2024-03-25 06:58:53

原理说明

原代码的问题在于单线程执行:任务运行时会阻塞主循环的schedule.run_pending()调用,直到任务结束才会继续检查下一次调度时间。通过线程异步执行任务,主调度循环可以持续按固定间隔触发任务,不受任务执行耗时的影响。

内容的提问来源于stack exchange,提问作者CrazyCoder

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 07:20:05