限制循环每分钟N次迭代

0 投票
4 回答
4489 浏览
提问于 2025-04-16 04:28

有人能帮我一下吗?我想在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

使用来自 itertoolsgrouper,可以参考这个 文档,再加上时间检查。

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

撰写回答