如何使用Python安排一个不受系统时间变化影响的周期性任务

时间:2016-04-21 17:04:10

标签: python python-2.7

我正在使用python的sched模块定期运行任务,我想我遇到过一个bug。

我发现它依赖于运行python脚本的系统的时间。例如,让我们说我想每5秒运行一次任务。如果我转发系统时间,则计划任务将按预期运行。但是,如果我将系统时间倒回到1天,则下一个计划任务将在5秒+ 1天内运行。

如果您运行下面的脚本,然后在几天前更改系统时间,那么您可以重现该问题。该问题可以在Linux和Windows上重现。

import sched
import time
import threading

period = 5
scheduler = sched.scheduler(time.time, time.sleep)

def check_scheduler():
    print time.time()
    scheduler.enter(period, 1, check_scheduler, ())

if __name__ == '__main__':
    print time.time()

    scheduler.enter(period, 1, check_scheduler, ())

    thread = threading.Thread(target=scheduler.run)
    thread.start()
    thread.join()
    exit(0)

任何人都有解决这个问题的python解决方案吗?

1 个答案:

答案 0 :(得分:3)

来自the sched documentation

  

class sched.scheduler(timefunc,delayfunc)

     

scheduler类定义了调度事件的通用接口。它需要两个功能来实际处理“外部”   world“ - timefunc应该可以不带参数调用,并返回一个   数字(“时间”,任何单位)。 delayfunc函数   应该可以用一个参数调用,与输出兼容   timefunc,应该延迟那么多时间单位。 delayfunc也将   在每个事件运行后使用参数0调用以允许其他事件   线程有机会在多线程应用程序中运行。

您遇到的问题是您的代码使用time.time()作为timefunc,其返回值(在没有参数的情况下调用时)是当前系统时间,因此会受到重新缠绕系统时钟的影响。

为了使您的代码免受系统时间的影响,您需要提供一个timefunc,它不依赖于系统时间,开始/当前时间戳等。

您可以编写自己的功能,例如,返回自您的流程启动以来的秒数,您必须在代码中实际计算(即不要... t compute it基于时间戳增量)。 time.clock()函数可能有帮助,如果它基于CPU时间计数器,但我不确定这是否真实。