We use cron-jobs to control lab instruments once a minute in the lab. I noticed that specifying 'once a minute' to cron produces a start-time for the job with quite a bit of variability. Usually the job starts at 1s past the minute, but sometimes 2s. There's also a random delay of 20 ms to 50 ms (but sometimes up to 300 ms). This probably depends a lot on the hardware. So if we assume the cron-job starts 1s past the minute the worst error I saw in the test above is 1.3 seconds.
Here's a very simple synchronization idea: first ask for a time-stamp, then wait until we are at an inter-second boundary, then continue. This makes the cron-job continue at the inter-second boundary with a maximum error of 6 ms, a fair improvement over 1.3 seconds without any sync code.
import datetime import time dt1 = datetime.datetime.now() # time-stamp when cron decides to run us usecs_to_go = 1e6-dt1.microsecond # we want to run at an inter-second boundary secs_target = 5 # we want to run at 5 seconds past minute secs_to_go = secs_target - dt1.second -1 # amount of waiting to do. time.sleep( secs_to_go+ usecs_to_go/1.0e6 ) dt2 = datetime.datetime.now() # now we are synced!? fn = '/home/user/my_cron_log.txt' # write to logfile for later analysis. with open(fn,'a+') as f: f.write(str(dt1) +" %02d.%06d" % (dt1.second, dt1.microsecond) + ' run!\n') f.write(str(dt2) +" %02d.%06d" % (dt2.second, dt2.microsecond) + ' sync!\n') f.write('\n') |
The way to enable this to run from crontab is to add something like this to crontab (use crontab -e):
# m h dom mon dow command * * * * * /usr/bin/python /home/user/cron_sync.py
Where cron_sync.py is the name of the script above.
I'd be interested in hearing how this works on other hardware, or if there are some alternative solutions.