让python在给定时间启动线程时出现问题
我正在写一个小应用程序,它可以在每天09:00醒来,从一些来源获取数据。然而,当我查看我的日志和数据库条目时,我看到它在09:00执行,在10:00再次执行 刮削过程最多需要15分钟才能完成,这让我完全不知所措让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
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
语句没有机会生成所述输出