Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Run a python function every second

Tags:

python

What I want is to be able to run a function every second, irrelevant of how long the function takes (it should always be under a second). I've considered a number of options but not sure which is best.

If I just use the delay function it isn't going to take into account the time the function takes to run.

If I time the function and then subtract that from a second and make up the rest in the delay it's not going to take into account the time calculations.

I tried using threading.timer (I'm not sure about the ins and outs of how this works) but it did seem to be slower than the 1s.

Here's the code I tried for testing threading.timer:

def update(i):
    sys.stdout.write(str(i)+'\r')
    sys.stdout.flush()
    print i
    i += 1
    threading.Timer(1, update, [i]).start()

Is there a way to do this irrelevant of the length of the time the function takes?

like image 995
DNN Avatar asked Dec 01 '22 06:12

DNN


2 Answers

This will do it, and its accuracy won't drift with time.

import time

start_time = time.time()
interval = 1
for i in range(20):
    time.sleep(start_time + i*interval - time.time())
    f()
like image 91
2 revs Avatar answered Dec 06 '22 16:12

2 revs


The approach using a threading.Timer (see code below) should in fact not be used, as a new thread is launched at every interval and this loop can never be stopped cleanly.

# as seen here: https://stackoverflow.com/a/3393759/1025391
def update(i):
  threading.Timer(1, update, [i+1]).start()
  # business logic here

If you want a background loop it is better to launch a new thread that runs a loop as described in the other answer. Which is able to receive a stop signal, s.t. you can join() the thread eventually.

This related answer seems to be a great starting point to implement this.

like image 26
moooeeeep Avatar answered Dec 06 '22 15:12

moooeeeep