This question already has an answer here:
I am working on Windows. I want to execute a function foo() every 10 seconds.
How do I do this?
This question already has an answer here:
I am working on Windows. I want to execute a function foo() every 10 seconds.
How do I do this?
At the end of
foo()
, create aTimer
which callsfoo()
itself after 10 seconds.Because,
Timer
create a newthread
to callfoo()
.You can do other stuff without being blocked.
Surprised to not find a solution using a generator for timing. I just designed this one for my own purposes.
This solution: single threaded, no object instantiation each period, uses generator for times, rock solid on timing down to precision of the
time
module (unlike several of the solutions I've tried from stack exchange).Note: for Python 2.x, replace
next(g)
below withg.next()
.Results in, for example:
Note that this example includes a simulation of the cpu doing something else for .3 seconds each period. If you changed it to be random each time it wouldn't matter. The max in the
yield
line serves to protectsleep
from negative numbers in case the function being called takes longer than the period specified. In that case it would execute immediately and make up the lost time in the timing of the next execution.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:
-
This will insert a 10 second sleep in between every call to
foo()
, which is approximately what you asked for when the call completes quickly.edit: To do other things while your
foo()
is being called in a background threadSimply sleeping for 10 seconds or using
threading.Timer(10,foo)
will result in start time drift. (You may not care about this, or it may be a significant source of problems depending on your exact situation.) There can be two causes for this - inaccuracies in the wake up time of your thread or execution time for your function.You can see some results at the end of this post, but first an example of how to fix it. You need to track when your function should next be called as opposed to when it actually got called and account for the difference.
Here's a version that drifts slightly:
Its output looks like this:
You can see that the sub-second count is constantly increasing and thus, the start time is "drifting".
This is code that correctly accounts for drift:
Its output looks like this:
Here you can see that there is no longer any increase in the sub-second times.
If your events are occurring really frequently you may want to run the timer in a single thread, rather than starting a new thread for each event. While accounting for drift this would look like:
However your application will not exit normally, you'll need to kill the timer thread. If you want to exit normally when your application is done, without manually killing the thread, you should use
If you meant to run foo() inside a python script every 10 seconds, you can do something on these lines.