跳转到主内容
极星编程网:以代码为星,赴技术山海!

Python怎么做定时任务_schedule模块实现轻量级不阻塞定时轮询脚本

schedule.run_pending()需手动循环调用,否则只执行一次;须配合while True和time.sleep()避免CPU占用或延迟;Web服务中应放后台守护线程运行;job异常会中断所有任务,需try/except或装饰器兜底;复杂场景建议换APScheduler。 schedule.run_pending() 为什么没反应? 根本原因:它只是检查并执行一次待触发任务,不自动循环。你得自己加个
while True
配合
time.sleep()
,否则脚本跑完就退出,定时器压根没机会干活。 常见错误现象:
schedule.every(10).seconds.do(job)
写了,但程序启动后啥也不输出、没执行 必须手动轮询:在主逻辑里持续调用
schedule.run_pending()
,比如每秒检查一次
time.sleep(1)
是关键——不加会疯狂占用 CPU;设太长(如 5 秒)会导致任务延迟最多达该间隔 别用
time.sleep(0)
或
pass
循环,那是空转,等同于没 sleep 怎么避免阻塞主线程(比如 Flask/FastAPI 服务)? schedule 本身是同步的,直接丢进 Web 框架主线程里跑,等于把整个服务卡住。真要共存,得把它扔进独立线程里跑,且线程得设为
daemon=True
,不然主程序关不掉。 典型错误:在
app.run()
前写个
while True
,结果 Web 服务根本起不来 正确做法:用
threading.Thread
启一个后台线程,里面跑
schedule.run_pending()
+
time.sleep()
务必加
thread.daemon = True
,否则 Ctrl+C 时线程还在后台活着,进程杀不干净 示例片段:
import threading
def run_scheduler():
while True:
schedule.run_pending()
time.sleep(1)
t = threading.Thread(target=run_scheduler)
t.daemon = True
t.start()
job 函数抛异常会导致后续所有任务停摆吗? 会。schedule 不做异常隔离,默认一崩全停。哪怕只是某个 job 里写了
1/0
,之后所有定时任务都再不会执行。 Python 3.14.3 微软官方的 Python 扩展,是 VS Code 安装量最高的扩展(209M+)。集成 IntelliSense(通过 Pylance)、调试(通过 Python Debugger)、代码检查、格式化、重构和单元测试等功能。支持 Jupyter Notebook、虚拟环境管理和多 Python 版本切换。 下载 常见现象:某次日志报
ZeroDivisionError
后,后续本该每分钟跑的任务彻底静默 解决方法:在每个 job 函数内部包一层
try/except
,至少 catch
Exception
,别让它冒出去 不要依赖 schedule 自带的错误处理——它没有 如果需要统一兜底,可封装一个装饰器:
def safe_job(func):
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
print(f"Job {func.__name__} failed: {e}")
return wrapper

@safe_job
def my_task():
...
schedule 和 APScheduler 到底选哪个? 看需求复杂度。schedule 就是“够用就行”的轻量选择;一旦要持久化、分布式、精确到毫秒或失败重试,立刻换 APScheduler。 立即学习 “ Python免费学习笔记(深入) ”; schedule 优势:零依赖、代码少、易读易改,适合单机脚本、开发期临时轮询、CI 中简单触发 schedule 劣势:无任务状态管理、不支持 misfire 处理、不能跨进程、时间精度受
sleep
间隔限制 APScheduler 适合场景:生产环境长期运行、需存储任务状态(比如用 SQLAlchemy)、要和 Celery 配合、要求错过时间后自动补跑 别为了“看起来更专业”硬上 APScheduler——多出 3 个依赖、配置项翻倍、出问题排查路径更长 实际用 schedule 时,最常被忽略的是异常传播和线程生命周期管理。这两点不出问题时感觉不到,一出就是静默失效,查日志都找不到入口。

相关文章