4

I want to run a piece of code at exact time intervals (of the order of 15 seconds) Initially I used time.sleep(), but then the problem is the code takes a second or so to run, so it will get out of sync.

I wrote this, which I feel is untidy because I don't like using while loops. Is there a better way?

import datetime as dt
import numpy as np

iterations = 100
tstep = dt.timedelta(seconds=5)
for i in np.arange(iterations):
    startTime = dt.datetime.now()
    myfunction(doesloadsofcoolthings)
    while dt.datetime.now() < startTime + tstep:
        1==1
AndyMoore
  • 1,324
  • 2
  • 11
  • 18

3 Answers3

8

Ideally one would use threading to accomplish this. You can do something like

import threading
interval = 15

def myPeriodicFunction():
    print "This loops on a timer every %d seconds" % interval

def startTimer():
    threading.Timer(interval, startTimer).start()
    myPeriodicFunction()

then you can just call

startTimer()

in order to start the looping timer.

Jon Deaton
  • 3,943
  • 6
  • 28
  • 41
  • does this mean that if the process is still running, it starts the next process on a diferent cpu thread? – AndyMoore Jul 20 '17 at 18:16
  • This is not exact. I experienced a shift of around .01 seconds at every loop. My periodic function was just print(datetime.now()) – cheesus May 18 '21 at 10:12
2

Consider tracking the time it takes the code to run (a timer() function), then sleeping for 15 - exec_time seconds after completion.

start = datetime.now()
do_many_important_things()
end = datetime.now()

exec_time = end - start
time.sleep(15-exec_time.total_seconds())
Jared Nielsen
  • 3,669
  • 9
  • 25
  • 36
2

You can use a simple bash line:

watch -n 15m python yourcode.py