让python在给定时间启动线程的问题

时间:2013-04-30 20:23:19

标签: python

我正在编写一个小应用程序,每天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

3 个答案:

答案 0 :(得分: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

你必须幸运才能实现这一点,但谁知道: - )


BTW time.sleep(30)表示您可能在09:00进入两次循环。我不明白这与我们正在讨论的问题有什么关系。

答案 1 :(得分:2)

为了清楚起见,我将在这个答案中总结一些建议。首先,我的猜测是问题实际上是科斯描述的问题,我认为它的发生频率比你预期的要多。拨打time.strftime两次(实际上是四次,但其中两次仅用于打印)意味着你要在time.localtime下进行两(4)次通话,因为你每三十次检查一次几秒钟,很有可能如果你在非常接近一分钟的时间内完成,那么你最终会在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,否则您可能会发现自己开始worker1和{{1很多次在9:01之前出现。

最后,它绝对值得关注系统调度程序,因为正如人们所说,让操作系统处理这些东西更好。 Windows使用本机功能(管理工具下的任务计划程序)可以轻松地完成计划任务。我不知道* nix,但我确定它不会那么糟糕。

答案 2 :(得分: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()。