在企业自动化流程、数据周期更新、本地脚本执行等场景中,定时任务调度器 是不可或缺的一类工具。尽管 Linux 有 crontab,Windows 有任务计划,但它们不够灵活,缺乏图形界面,不适合动态启停、可视化控制等需求。
本文将带你实现一个 本地运行的多线程定时任务调度器,具备以下功能:
多任务并行运行(非阻塞)
每个任务支持独立间隔设置
支持任务启动 / 停止 / 删除 / 修改
支持即时日志打印与输出历史
支持通过 GUI 或配置文件动态加载任务
数据接口定时轮询
文件自动打包、清洗、转移
远程主机检测、邮件提醒
本地脚本定时自动执行
技术 | 用途 |
---|---|
threading | 多任务并发 |
tkinter | 图形化界面 |
queue | 线程通信、日志传递 |
time / datetime | 时间调度逻辑 |
json | 加载任务配置 |
logging | 日志打印和追踪 |
bash
复制编辑
multi_timer_scheduler/ ├── main.py # 程序入口 ├── scheduler.py # 核心调度引擎 ├── task_config.json # 可选任务配置 ├── gui.py # 控制面板 GUI └── utils.py # 公共函数
python
复制编辑
import threading import time from datetime import datetime class ScheduledTask(threading.Thread): def __init__(self, name, interval, action, log_callback): super().__init__() self.name = name self.interval = interval # 秒 self.action = action self.log = log_callback self._running = threading.Event() self._running.set() def run(self): self.log(f"[{self.name}] 启动,周期 {self.interval}s") while self._running.is_set(): start = time.time() try: self.action(self.log) except Exception as e: self.log(f"[{self.name}] 执行异常:{str(e)}") elapsed = time.time() - start sleep_time = max(0, self.interval - elapsed) time.sleep(sleep_time) self.log(f"[{self.name}] 停止") def stop(self): self._running.clear()
每个任务独立线程运行,通过传入 action(log)
执行具体逻辑,log
可输出到界面或文件。
python
复制编辑
def dummy_action(log): now = datetime.now().strftime("%H:%M:%S") log(f" 当前时间:{now}")
你也可以在实际项目中换成上传、下载、接口请求等功能。
python
复制编辑
import tkinter as tk from tkinter import scrolledtext, simpledialog, messagebox from scheduler import ScheduledTask from functools import partial import threading class SchedulerGUI: def __init__(self, root): self.root = root self.root.title("多线程任务调度器") self.tasks = {} self.build_ui() def build_ui(self): tk.Button(self.root, text="添加任务", command=self.add_task_dialog).pack(pady=5) self.task_frame = tk.Frame(self.root) self.task_frame.pack() self.log_area = scrolledtext.ScrolledText(self.root, height=15) self.log_area.pack(fill=tk.BOTH, expand=True) def add_task_dialog(self): name = simpledialog.askstring("任务名称", "请输入任务名称:") try: interval = int(simpledialog.askstring("周期秒数", "请输入执行间隔(秒):")) except: messagebox.showerror("错误", "请输入整数") return # 示例任务(可换为自定义脚本) task = ScheduledTask(name, interval, dummy_action, self.log) task.start() self.tasks[name] = task row = tk.Frame(self.task_frame) tk.Label(row, text=name, width=20).pack(side=tk.LEFT) tk.Button(row, text="停止", command=partial(self.stop_task, name)).pack(side=tk.LEFT) row.pack() self.log(f"任务 [{name}] 已添加") def stop_task(self, name): task = self.tasks.pop(name, None) if task: task.stop() self.log(f"任务 [{name}] 已停止") def log(self, msg): self.log_area.insert(tk.END, msg + "\n") self.log_area.see(tk.END)
python
复制编辑
import tkinter as tk from gui import SchedulerGUI if __name__ == "__main__": root = tk.Tk() app = SchedulerGUI(root) root.geometry("600x500") root.mainloop()
用户点击「添加任务」,输入名称与时间间隔,即可添加后台运行的定时任务线程。
每个任务通过传入的 log()
输出信息,集中展示在日志区域。
每个任务配有「停止」按钮,点击即可终止任务线程。
在 task_config.json
中添加预设任务:
json
复制编辑
[ { "name": "打印时间", "interval": 5 }, { "name": "测试接口", "interval": 10 } ]
在程序启动时自动加载:
python
复制编辑
def load_from_config(gui): import json with open("task_config.json", "r", encoding="utf-8") as f: items = json.load(f) for item in items: name = item["name"] interval = item["interval"] task = ScheduledTask(name, interval, dummy_action, gui.log) task.start() gui.tasks[name] = task gui.log(f"[{name}] 来自配置文件的任务启动")
功能方向 | 拓展内容 |
---|---|
任务持久化 | 任务配置存入 SQLite,支持任务重启恢复 |
脚本加载 | 每个任务加载外部 Python 脚本执行 |
调度条件 | 除了周期,还支持定点触发、一次性触发 |
并发任务 | 同一任务支持并行执行多个实例 |
状态监控 | 展示当前线程数量、任务状态、异常信息 |
跨平台部署 | 打包为 EXE 或 Mac App 发布 |
通过本文我们实现了一个真正可用的本地多线程定时任务调度器,具有以下优点:
图形界面,简单直观
多任务并发,互不干扰
自定义任务逻辑,易于拓展
可集成配置加载、日志输出等功能
这类工具广泛用于数据处理、接口自动化、本地脚本运行场景中,属于实用价值极高、工程化可控的实战项目。