I want to have a loop be executed once every minute when datetime.utcnow().second
is zero.
So far I have this
while True:
while datetime.utcnow().second != 0: pass
do_something()
But the problem with this is that I am wasting cpu processes. I would use time.sleep(60)
, but I don't know how it would sync with the UTC clock, because time.sleep(60)
could stray from the official UTC time as time passes.
The naive approach would be too change the
pass
to asleep (1)
which would greatly ease the CPU pressure, but you run the risk of missing the zero-second if for some reason you get12:30:59.99999
followed by12:31:01.00001
.You could opt for a two-stage approach. While there's more than three seconds to go, wait for a longer time based on the amount of time to go. Otherwise, wait for one second.
Something like the following fully functional Python program will illustrate what I mean:
The output on my system is:
which is pretty much what you're after.
This function will basically do one wait that gets you very close to the end of the minute and then wake up every second until it cycles over.
So, for example, let's say it's
12:21:13
. Becausesecs
is less than57
, it will wait57 - 13
or enough to get you up to about12:21:57
.From there, it will simply sleep one second at a time until the
second
becomes less than57
. In other words, when we roll into the next minute.By doing it this way rather than trying to detect the zero second, you also bypass the possibility on missing a minute.
And, if you want to ensure you get as close to the minute rollover as possible, you can replace the
sleep (1)
with apass
. That way, you'll run at full CPU grunt for at most three seconds out of sixty (averaging 5%) and get about as close to the minute rollover as possible.When I perform that little modification, I get:
Best way I can think of would be to sleep until the next minute:
If you want to be really precise:
This sleeps for exactly the amount of time necessary to reach the next minute, with subsecond precision.
EDITED to fix minute rollover bug.
Interesting problem python does have a way to schedule events using sched and to make it reoccurring you can just schedule it again and again and so on ...
Here how it would look like.
interesting, it seems to be pretty accurate, with a slight overhead probably due to the time it takes to execute the actual instructions, I guess we need to take them into account, if we want perfect accuracy ...