Python简单的任务调度器

这段代码实现了一个简单的任务调度器,用于在指定的时间执行特定任务。以下是对这段代码的详细解释:

代码导入部分

  • import threading: 导入 Python 的 threading 模块,允许在单独的线程中运行任务调度器,从而不阻塞主线程的执行。
  • from apscheduler.schedulers.blocking import BlockingScheduler: 从 APScheduler 库中导入 BlockingScheduler 类。BlockingScheduler 是一个阻塞的调度器,适用于在主线程中运行任务调度。
  • from datetime import datetime: 导入 datetime 模块,用于获取当前的日期和时间,以便在任务执行时打印日志信息。

TaskScheduler

  • __init__ 方法:

    • 创建一个 BlockingScheduler 实例,并将其赋值给 self.scheduler。这个调度器将用于管理和调度任务。
  • add_daily_task 方法:

    • 定义一个每天在指定时间运行的任务。
    • 使用 cron 触发器设置任务的执行时间(小时、分钟、秒)。
    • add_job 方法用于添加任务到调度器中,func 为要执行的任务函数,id 是任务的唯一标识符,args 是传递给任务函数的参数。
  • add_cron_task 方法:

    • 定义一个基于 cron 表达式的任务。
    • 解析输入的 cron 表达式(格式为 “分钟 小时 日期 月份 星期几”),并验证其包含五个字段。
    • 使用 cron 触发器设置任务的执行时间,类似于 add_daily_task
  • start 方法:

    • 启动调度器,开始执行已调度的任务。
    • 使用 try-except 块捕获 KeyboardInterruptSystemExit 异常,以便在用户中断或系统退出时安全地停止调度器。

task_register 函数

  • 参数 bot: 接受一个代表机器人实例的参数(在这里是一个字符串)。

  • 内部函数 trigger_report_command:

    • 定义了一个简单的任务函数,用于模拟任务的执行。
    • 打印当前时间以及任务执行的详细信息(包括模块名称、聊天 ID 和机器人实例)。
  • 创建 TaskScheduler 实例:

    • 初始化一个调度器实例,并添加日常任务和基于 cron 的任务。
  • 添加任务:

    • 每天4:00 AM执行的任务: 使用 add_daily_task 方法添加。
    • 每天9:10 AM执行的任务: 使用 add_cron_task 方法添加,采用 cron 表达式。
  • 启动调度器线程:

    • 创建一个新线程来运行调度器,以避免阻塞主线程。
    • 线程中调用 scheduler.start() 方法。

主程序逻辑

  • task_register("example_bot_instance"):

    • 调用 task_register 函数,用一个示例的机器人实例启动调度器。
  • 打印信息:

    • 在主线程中打印一条信息,表示调度器在后台运行,主线程可以继续执行其他任务。

这个代码示例展示了如何使用 APScheduler 库来定期执行任务,并通过多线程确保调度器在后台运行,从而不影响其他代码的执行。

完整代码

import threading
from apscheduler.schedulers.blocking import BlockingScheduler
from datetime import datetime

class TaskScheduler:
    def __init__(self):
        # 创建一个阻塞调度器实例
        self.scheduler = BlockingScheduler()

    def add_daily_task(self, task_func, task_name, hour=0, minute=0, second=0, *args):
        """添加一个每天在特定时间运行的任务"""
        self.scheduler.add_job(
            func=task_func,  # 要执行的任务函数
            trigger='cron',  # 使用cron触发器
            hour=hour,       # 设置小时
            minute=minute,   # 设置分钟
            second=second,   # 设置秒
            id=task_name,    # 任务名称
            args=args        # 传递给任务函数的参数
        )

    def add_cron_task(self, task_func, task_name, cron_expression, *args):
        """使用cron表达式添加一个任务"""
        fields = cron_expression.split()
        if len(fields) != 5:
            raise ValueError("Cron表达式必须包含5个字段(分钟、小时、日期、月份、星期几)")
        
        self.scheduler.add_job(
            func=task_func,                # 要执行的任务函数
            trigger='cron',                # 使用cron触发器
            minute=fields[0],              # cron表达式中的分钟字段
            hour=fields[1],                # cron表达式中的小时字段
            day=fields[2],                 # cron表达式中的日期字段
            month=fields[3],               # cron表达式中的月份字段
            day_of_week=fields[4],         # cron表达式中的星期几字段
            id=task_name,                  # 任务名称
            args=args                      # 传递给任务函数的参数
        )

    def start(self):
        """启动调度器"""
        try:
            print("启动调度器...")
            self.scheduler.start()
        except (KeyboardInterrupt, SystemExit):
            print("调度器已停止。")

def task_register(bot):
    chat_id = "example_chat_id"

    def trigger_report_command(bot, chat_id, module):
        # 打印执行任务的详细信息
        print(f"[{datetime.now()}] 执行{module}报告,聊天ID: {chat_id},机器人: {bot}")

    scheduler = TaskScheduler()
    
    # 每天4:00 AM执行的任务
    scheduler.add_daily_task(
        trigger_report_command, 
        "日报 04:00 AM", 
        4, 
        0, 
        0, 
        bot, 
        chat_id, 
        "市场"
    )
    
    # 使用cron表达式每天9:10 AM执行的任务
    scheduler.add_cron_task(
        trigger_report_command, 
        "Cron报告 09:10 AM", 
        "10 9 * * *", 
        bot, 
        chat_id, 
        "市场"
    )

    # 在一个单独的线程中启动调度器
    scheduler_thread = threading.Thread(target=scheduler.start)
    scheduler_thread.start()

# 示例调用
task_register("example_bot_instance")

# 继续执行其他代码
print("调度器正在后台运行。")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值