[英]How to break a while loop after some minutes?
我的 python 程序中有一个 while 循环,我想在 5 分钟后break
这个循环,我目前正在使用以下代码:
start_time = time.time()
while time.time() - start_time < 300:
# do something
但是,每次迭代都需要额外的时间来计算time.time() - start_time < 300:
部分。 例如,如果我使用具有 30000 次迭代的for
循环并持续 5 分钟,则上述代码执行的迭代次数少于此次数。
我该怎么办? 我必须在 5 分钟后中断循环,我只想按时间处理这个问题,而不是通过for
循环迭代。
我的一位朋友建议使用datetime包,但我不知道它是如何工作的。
上面的代码执行的迭代次数比这少。
一个可能的原因是检查时间本身需要时间。 因此,您可以不那么频繁地检查时间:
start_time = time.time()
lv = 0
while True:
if lv == 100: # check time only once in 100 iterations
if time.time() - start_time > 300:
break
else:
lv = 0
# do something
lv +=1
听起来需要为我实现超时。 您可以使用内置threading
模块按以下方式执行此操作:
import time
from threading import Thread, Event
stop = Event()
def function():
while not stop.is_set():
print('*')
time.sleep(1)
thread = Thread(target=function)
thread.start()
thread.join(timeout=60)
stop.set()
上面的代码只是每秒打印*
60
秒。
我认为使用线程和睡眠是最好的方法。 您可以使用 lambda 函数以一种简单的方式来创建一个休眠的后台线程,并简单地检查该线程是否仍在您的循环中运行(时间到时中断循环):
from threading import Thread
from time import sleep
fiveMinutes = Thread(target=lambda:sleep(300)) # 5 min sleeping thread (300 seconds)
fiveMinutes.start() # start wait time
for i in range(10**10): # <-- this represents your loop condition
# ...
if not fiveMinutes.is_alive(): break # break after 5 minutes elapsed
# ...
这应该会为您的处理循环增加更少的开销,因此超时迭代应该非常接近处理相同迭代次数的有效时间。
[编辑] 线程/睡眠 vs time.time()
我做了一些更多的测试,使用休眠线程和最佳使用 time() 函数之间几乎没有区别。 每次迭代的开销小于一微秒:
from time import time
fiveMinutes = time() + 300
for i in range(10**10): # <-- this represents your loop condition
# ...
if time() > fiveMinutes : break # break after 5 minutes elapsed
# ...
如果您在 1 分钟的样本中得到 3 秒的差异,我会怀疑您的逻辑的处理时间有其自身的可变性(即在循环中运行相同数量的迭代会因一次运行而异)。 要么是这样,要么您检查超时的次数比 11,311 次迭代建议的次数要多得多(可能通过检查嵌套循环)。 在我的测试中,在执行 41,000 次迭代的 60 秒样本中,两种方法的变化不到 0.5 秒:time() 为 +0.37 秒,线程为 +0.23 秒。
(稍后稍作修改,我想我大致同意 Alain。经过一定次数的迭代后,我从中断中获得了显着的加速,但是无论是直接使用线程、time.time 还是部分采样方法,几乎所有其中一些最终会降低循环时间time.time()
本身可能已经相当高度优化,所以所有额外的布尔值和避免使用太多的东西可能不会改善太多)。
不知道它是否更有效,但您可以尝试一个线程和一个共享的可变对象来驱动循环。 这是 0.5 秒的测试。
import time
from threading import Thread
def myfunc(mutable_):
time.sleep(0.5)
mutable_.value = False
print("done")
class Mutable:
value = True
mutable_ = Mutable()
t = Thread(target=myfunc, args=(mutable_,))
start = time.time()
t.start()
while mutable_.value:
print(time.time() - start)
我不知道的是,循环对mutable_.value
的属性访问(不需要直接涉及线程)是否比轮询线程本身便宜得多。
现在,在我的测试中,在线程尚未更新值的情况下存在一些差异,因此与使用自己的本地时间检查相比,循环运行了一点。 可能可以将您的线程超时设置为 299.9 秒,靠近并更仔细地完成。
这是一个 v2 使用线程睡眠来获得大部分方式(即 0.49)和一个通常短路的time.time()
检查以完成。
def myfunc(mutable_, looptime):
time.sleep(looptime)
mutable_.value = False
t = Thread(target=myfunc, args=(mutable_,.49))
t.start()
start = time.time()
while mutable_.value or (time.time() - start <= .5):
print(time.time() - start)
试试这个:
start_time = time.time() + 300
while True:
if time.time() > start_time:
break
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.