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,124
  • 2
  • 10
  • 17

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,245
  • 5
  • 24
  • 39
  • 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,319
  • 8
  • 23
  • 35
1

You can use a simple bash line:

watch -n 15m python yourcode.py