Here's a simple single threaded sleep based version that drifts, but tries to auto-correct when it detects drift.
NOTE: This will only work if the following 3 reasonable assumptions are met:
- The time period is much larger than the execution time of the function being executed
- The function being executed takes approximately the same amount of time on each call
- The amount of drift between calls is less than a second
-
from datetime import timedelta
from datetime import datetime
def exec_every_n_seconds(n,f):
first_called=datetime.now()
f()
num_calls=1
drift=timedelta()
time_period=timedelta(seconds=n)
while 1:
time.sleep(n-drift.microseconds/1000000.0)
current_time = datetime.now()
f()
num_calls += 1
difference = current_time - first_called
drift = difference - time_period* num_calls
print "drift=",drift