1

我正在编写一个小应用程序,旨在每天 09:00 醒来并从某些来源获取数据。但是,当我查看我的日志和数据库条目时,我看到它在 09:00 和 10:00 再次执行。

抓取过程最多需要 15 分钟才能完成,这让我完全难过。

while 1:

    if time.strftime("%H") == "09" and time.strftime("%M") == "00":
        print "Starting at: " + time.strftime("%H") + ":" + time.strftime("%M")
        worker1.startThread()
        worker2.startThread()

    time.sleep(30)

在我的日志中,我基本上看到

Starting at: 09:00
     <snip>
Starting at: 10:00
4

3 回答 3

3

这个场景怎么样:

while 1:                               # 09:59:59.97 

    if time.strftime("%H") == "09"     # 09:59:59.99  
    and time.strftime("%M") == "00":   # 10:00:00.01

你必须很幸运才能发生这种情况,但谁知道:-)


顺便说一句time.sleep(30),您可能会在 09:00 进入循环两次。不过,我看不出这与我们正在讨论的问题有什么关系。

于 2013-04-30T20:31:10.217 回答
2

为清楚起见,我将总结此答案中的一些建议。首先,我的猜测是问题实际上是 Kos 所描述的问题,而且我认为它发生的频率比您预期的要多。拨打两个电话time.strftime(实际上是四个,但其中两个只是用于打印)意味着您在后台拨打了两个(四个)电话time.localtime,并且由于您每 30 秒检查一次,因此很有可能如果您完成非常接近精确的一分钟,您最终会得到合理地跨越 10:00 小时的值。这就是我要解决的方法:

while True:
    t = time.localtime()
    if t[3:5] == (9, 0): # Compare (hour, day) numerically
        print time.strftime("Starting at: %H:%M", t)
        worker1.startThread()
        worker2.startThread()
        time.sleep(get_nap_length())
    else:
        time.sleep(59) # No need to sleep less than this, even being paranoid.

def get_nap_length():
    '''Returns approximate number of seconds before 9:00am tomorrow.

    Probably implementing this would be easiest with the datetime module.'''

get_nap_length如果您愿意,我会将实施留给您。为了安全起见,我会让它返回明天早上 8:58 之前的秒数。实现这一点将减少您通过循环的“无用”次数,从而减少您以某种方式出错的机会。请注意,如果您执行此操作,您还需要else从我上面提供的代码中删除 ,否则您可能会发现自己在 9:01 到来之前开始worker1worker2很多次。

最后,系统调度程序绝对值得一看,因为正如人们所说,让操作系统处理这些东西会更好。Windows 使用本机功能(管理工具下的任务计划程序)使计划任务相当容易。我不知道*nix,但我相信它不会那么糟糕。

于 2013-04-30T22:02:23.343 回答
0

您可以像这样排除@Kos提出的问题:

while 1:

    now = time.localtime()
    hour = time.strftime("%H", now)
    min = time.strftime("%M", now)
    if hour == "09" and min == "00":
        print "Starting at: " + hour + ":" + min
        worker1.startThread()
        worker2.startThread()

    time.sleep(30)

这样您就不会在移动目标上运行 strftime() 。

于 2013-04-30T21:10:12.360 回答