2010-09-22 3 views
0

Может кто-нибудь, пожалуйста, помогите мне с ограничением цикла на 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 ... 

Как бы я сделать проверку времени/сна, чтобы дать правильный поток. Я не беспокоюсь о блокировке исполняемого потока/процесса, пока он ждет.

Благодаря

+0

Какую работу вы планируете в цикле? – pszilard

ответ

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 
+0

Спасибо, но если я поставлю код обработки «print items», весь массив будет напечатан там тогда, а не печать 5, а затем до 60 секунд, прежде чем продолжить. – Jason

+0

@ Джейсон. Вы не сказали, что хотите распечатать их группами. Это будет обрабатывать их по одному, как вы просили. когда вы распечатываете список, _ course_ весь массив get напечатан. – aaronasterling

+0

@AaronMcSmooth: для этого вам нужна правильная оценка 'limit' s.t. 'limit * iterationTime <= 1 min' * и * это должно быть верно для всего выполнения. – pszilard

0

Используйте grouper из itertoolsrecipes, в сочетании с проверкой времени.

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) 
+0

Спасибо, это не с: TypeError: объект 'datetime.datetime' не является итерируемым – Jason

+0

так же, как и для AaronMcSmooth, вам нужно знать 'limit', и знать его очень хорошо :) – pszilard

+0

@pszilard. katrialex взял тот же самый лад, который я сделал, и выполнил все пять в начале, а затем вычислил оставшееся время для сна. – aaronasterling

0

Это очень сильно зависит от типа работы, которую вы делаете внутри цикла и от того, насколько точно вы хотите, чтобы этот механизм работать.

ATM Я могу придумать 2 возможных схемы:

  • Если одна итерации занимает около постоянного времени, чем вы могли бы рассчитывать в среднем от первых нескольких итераций и «сон» для 1 - iterationTime потом.
  • В противном случае вы можете опросить время и пересчитать средний каждый шаг (или несколько шагов).

В зависимости от стандартного отклонения одного времени выполнения одной схемы обе схемы могут работать достаточно хорошо, но если время выполнения очень варьируется, ни один из них не будет. Кроме того, если вам нужны равномерно распределенные циклы циклов и не только поддерживать средний/мин, вы должны распределять сон и выполнять одно за каждой итерацией.

Я не достаточно хорошо знаком с Python, чтобы узнать, как дорого стоит запросить время и какие другие проблемы, связанные с Python, могут появиться со сном.

Смежные вопросы