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

让python在给定时间启动线程时出现问题,python,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.s

我正在写一个小应用程序,它可以在每天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
从09:00开始
开始时间:10:00

这个场景怎么样:

while 1:                               # 09:59:59.97 

    if time.strftime("%H") == "09"     # 09:59:59.99  
    and time.strftime("%M") == "00":   # 10:00:00.01
要想发生这种事,你得走运,但谁知道呢:-)



顺便说一句,时间。睡眠(30)意味着你可能在09:00进入循环两次。不过,我看不出这与我们正在讨论的问题有什么关系。

这个场景如何:

while 1:                               # 09:59:59.97 

    if time.strftime("%H") == "09"     # 09:59:59.99  
    and time.strftime("%M") == "00":   # 10:00:00.01
要想发生这种事,你得走运,但谁知道呢:-)



顺便说一句,时间。睡眠(30)意味着你可能在09:00进入循环两次。不过,我看不出这与我们正在讨论的问题有什么关系。

您可以排除@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()。

您可以排除@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()。

为了清楚起见,我将在这个答案中总结一些建议。首先,我的猜测是,这个问题实际上就是科斯所描述的,我认为它发生的频率比你想象的要高。对
time.strftime
进行两次调用(实际上是四次,但其中两次仅用于打印)意味着您要在引擎盖下对
time.localtime
进行两(四)次调用,并且由于您每三十秒检查一次,如果您在非常接近一分钟的时间内完成,你最终会发现,价值观往往会跨越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\u nap\u length
的实现留给您。为了安全起见,我会让它返回到明天早上8:58的秒数。实现这一点将减少你通过循环的“无用”次数,从而以某种方式减少你失火的机会。请注意,如果不执行此操作,您还需要从我上面提供的代码中删除
else
,否则您可能会发现自己在9:01到来之前多次启动
worker1
worker2


最后,值得一看的是系统调度器,因为正如人们所说,让操作系统来处理这些事情更好。Windows使用本机功能(管理工具下的任务调度器)使计划任务变得相当简单。我不知道*nix,但我相信它不会那么糟糕。

为了清楚起见,我将在这个答案中总结一些建议。首先,我的猜测是,这个问题实际上就是科斯所描述的,我认为它发生的频率比你想象的要高。对
time.strftime
进行两次调用(实际上是四次,但其中两次仅用于打印)意味着您要在引擎盖下对
time.localtime
进行两(四)次调用,并且由于您每三十秒检查一次,如果您在非常接近一分钟的时间内完成,你最终会发现,价值观往往会跨越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\u nap\u length
的实现留给您。为了安全起见,我会让它返回到明天早上8:58的秒数。实现这一点将减少你通过循环的“无用”次数,从而以某种方式减少你失火的机会。请注意,如果不执行此操作,您还需要从我上面提供的代码中删除
else
,否则您可能会发现自己在9:01到来之前多次启动
worker1
worker2


最后,值得一看的是系统调度器,因为正如人们所说,让操作系统来处理这些事情更好。Windows使用本机功能(管理工具下的任务调度器)使计划任务变得相当简单。我不知道*nix,但我确信它不会那么糟糕。

调度工作通常最好使用操作系统调度程序ie crontab来完成。也就是说,当您运行此程序时,您是否有过值为“10”的情况?因为它看起来像是一个设置为10点开始的旧进程仍然在运行。像这样在脚本中控制它对我来说很方便。我已经检查了我正在运行的进程,没有旧实例的迹象-这是一个很好的建议。如果你在windows上,那么可能会很方便,我不知道。但我想,如果Windows没有好的调度程序,那么安装它就相当简单了。如果你认为这对你来说很方便,那你就错了。使用crontab比自己安排时间快得多,也方便得多。你为什么要单独调用strftime
strftime
?或者,就这一点而言,你为什么要对实际数字进行更自然的字符串比较呢?我的猜测是,所提到的@Kos场景发生的频率比您预期的要高,可以通过稍微重新构造代码来轻松修复:
t=time.localtime()
如果t[3:5]==(9,0):#做一些事情
同样,您可以在循环结束时做一些更好的事情,比如计算在下一次跑步之前你需要睡眠多少秒,这可能会完全抵消检查。到目前为止,这是一个相当复杂的问题。你有没有可能提供更多的信息?例如,我在Python文档中找不到
startThread
,如果你自己滚动,谁知道里面有什么?您的
print
语句没有机会生成所述输出