首页 > 解决方案 > 为什么我的计划任务在前几次之后以指数方式运行,而不是按计划的时间间隔运行?

问题描述

我正在为 Twitter 开发一个机器人,它每天在同一时间检查用户时间线,并搜索“每日推文”,从中解析数据、格式化数据,并将其作为推文从我的机器人发送。

目前,我一直在使用 Pythons schedule 模块以 6 个不同的时间间隔(@ 1:19 min、1:30 min、2、4、10 和 20 分钟后 00:00 UTC)读取用户时间线,以查看何时以及是否该用户在推特上发布了“每日推文”(通常在 5 分钟内发布推文,但最迟在 20 分钟内发布)。虽然这种方法在技术上按预期工作,但我想更改代码,以便用户发布每日推文的时间与我的机器人响应该推文的时间之间的延迟更少。本质上,我希望每天从特定时间开始一个小时的类似守护进程的行为。

schedule.every().day.at('19:01:19').do(daily_mode_inspector, False)  #
schedule.every().day.at('19:01:30').do(daily_mode_inspector, False)  #
schedule.every().day.at('19:02').do(daily_mode_inspector, False)  # at intervals, check for the daily change
schedule.every().day.at('19:04').do(daily_mode_inspector, False)  #
schedule.every().day.at('19:10').do(daily_mode_inspector, False)  #
schedule.every().day.at('19:20').do(daily_mode_inspector, True)  #

print('\nWaiting for next Daily Mode Inspection....')  

while True:

    schedule.run_pending()
    time.sleep(1)

我最近尝试的是只在 00:00 UTC 运行一个每日计划任务,并向函数添加一行代码,该daily_mode_inspector函数每 10 秒运行一次,直到满足条件,然后停止。

在测试我确信会是非常简单的代码时,我遇到了一个问题,它schedule.every(10).seconds.do(daily_mode_inspector)会产生一些不稳定的行为,因为它在前两次(第一次预定时间,然后是 10 秒之后)正确运行,但大约在第三次运行,它开始以指数方式运行,而不是线性运行,如果这有意义的话。为了更好地解释它,我以这种方式对其进行了测试:

import datetime
import schedule
import pytz

def utc_stamp():

    utc_time = datetime.datetime.now(tz=pytz.UTC).strftime('%X')
    return utc_time


def daily_inspector():

    schedule.every(10).seconds.do(daily_inspector)
    print('Hello World', utc_stamp())


schedule.every().day.at('14:30').do(daily_inspector)

while True:

    schedule.run_pending()

这会产生以下结果:

Hello World 19:30:00
Hello World 19:30:10
Hello World 19:30:20
Hello World 19:30:20
Hello World 19:30:30
Hello World 19:30:30
Hello World 19:30:30
Hello World 19:30:30
Hello World 19:30:40
Hello World 19:30:40
Hello World 19:30:40
Hello World 19:30:40
Hello World 19:30:40
Hello World 19:30:40
Hello World 19:30:40

我的期望是代码将每 10 秒运行一次,但实际上在第二次运行后,当它达到 10 秒间隔时,它将多次运行日常检查器代码,并且代码运行的时间越长,它只会变得更糟。我想知道我怎样才能让它每 10 秒运行一次我的功能,而不会导致上面的废话。

标签: python

解决方案


原因很简单,因为您创建了一个递归函数,即一个调用自身的函数。

要修复它,请将要执行的例程与执行它的调用隔离开来。

更新 daily_inspector() 如下:

def daily_inspector():
    schedule.every(10).seconds.do(do_routine)

然后定义do_routine如下:

def do_routine():
    print('Hello World', utc_stamp())

推荐阅读