限制循环每分钟N次迭代
有人能帮我一下吗?我想在Python中限制一个循环每分钟执行N次。
假设我有
limit = 5
for items in recvData:
# > limit iterations in past minute? -> sleep for 60 seconds from last iterations before proceeding? #
... do work ...
我该怎么做时间检查和让程序“睡一会儿”,这样才能保持正确的执行速度呢?我不担心在等待时会阻塞执行的线程或进程。
谢谢!
4 个回答
0
这主要取决于你在循环中做的工作类型,以及你希望这个机制有多准确。
目前我能想到两种可能的方案:
- 如果每次循环的时间差不多是固定的,你可以先计算前几次循环的平均时间,然后在之后的循环中“休眠”一段时间,具体时间是
1 - iterationTime
。 - 如果不是这样,你可以在每一步(或者每几步)检查一下时间,并重新计算平均时间。
根据你每次循环执行时间的标准差,这两种方案都能很好地工作,但如果执行时间变化很大,哪种方案都不太行。而且,如果你想让循环的时间分布均匀,而不仅仅是保持平均值或最小值,你需要在每次循环后都进行休眠。
不过,我对Python不够熟悉,不太清楚查询时间的开销有多大,以及在休眠时可能会遇到哪些Python特有的问题。
0
使用来自 itertools
的 grouper
,可以参考这个 文档,再加上时间检查。
import itertools, datetime, time
limit = 5
def grouper(n, iterable, fillvalue=None):
"grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx"
args = [iter(iterable)] * n
return itertools.izip_longest(fillvalue=fillvalue, *args)
for items in grouper(limit, recvData):
prev_minute = datetime.datetime.now().minute
for item in items:
# do stuff
_, _, _, _, minute, second, _ = datetime.datetime.now()
if minute == prev_minute:
time.sleep( 60 - second )
3
需要注意的是,这段代码并不是“硬实时”代码。由于操作系统的调度等原因,它的执行可能会有些偏差。不过,如果你不确定自己是否需要硬实时的要求,这段代码应该是足够用的。
import time
limit = 5
starttime = time.time()
for i, item in enumerate(recvData):
if not i + 1 % limit:
sleeptime =starttime + 60 - time.time()
if sleeptime > 0:
time.sleep(sleeptime)
starttime = time.time()
#processing code