What is the best way to repeatedly execute a function every x seconds?

后端 未结 18 2746
不知归路
不知归路 2020-11-21 06:04

I want to repeatedly execute a function in Python every 60 seconds forever (just like an NSTimer in Objective C). This code will run as a daemon and is effectively like call

18条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-21 06:17

    I use this to cause 60 events per hour with most events occurring at the same number of seconds after the whole minute:

    import math
    import time
    import random
    
    TICK = 60 # one minute tick size
    TICK_TIMING = 59 # execute on 59th second of the tick
    TICK_MINIMUM = 30 # minimum catch up tick size when lagging
    
    def set_timing():
    
        now = time.time()
        elapsed = now - info['begin']
        minutes = math.floor(elapsed/TICK)
        tick_elapsed = now - info['completion_time']
        if (info['tick']+1) > minutes:
            wait = max(0,(TICK_TIMING-(time.time() % TICK)))
            print ('standard wait: %.2f' % wait)
            time.sleep(wait)
        elif tick_elapsed < TICK_MINIMUM:
            wait = TICK_MINIMUM-tick_elapsed
            print ('minimum wait: %.2f' % wait)
            time.sleep(wait)
        else:
            print ('skip set_timing(); no wait')
        drift = ((time.time() - info['begin']) - info['tick']*TICK -
            TICK_TIMING + info['begin']%TICK)
        print ('drift: %.6f' % drift)
    
    info['tick'] = 0
    info['begin'] = time.time()
    info['completion_time'] = info['begin'] - TICK
    
    while 1:
    
        set_timing()
    
        print('hello world')
    
        #random real world event
        time.sleep(random.random()*TICK_MINIMUM)
    
        info['tick'] += 1
        info['completion_time'] = time.time()
    

    Depending upon actual conditions you might get ticks of length:

    60,60,62,58,60,60,120,30,30,60,60,60,60,60...etc.
    

    but at the end of 60 minutes you'll have 60 ticks; and most of them will occur at the correct offset to the minute you prefer.

    On my system I get typical drift of < 1/20th of a second until need for correction arises.

    The advantage of this method is resolution of clock drift; which can cause issues if you're doing things like appending one item per tick and you expect 60 items appended per hour. Failure to account for drift can cause secondary indications like moving averages to consider data too deep into the past resulting in faulty output.

提交回复
热议问题