1

So I want to make a loop like this (example simplified):

def main():
 while True:
  function1() #run this every 1s
  function2() #run this every 2s
  function3() #run this every 5s
  function4() #run this every 10s

Ideally, after 10s it should run function1 10 times, function2 5 times, function3 2 times,..etc.

My current approach is using a loop counter but it's far from ideal since the time spent for each loop is not accounted and is not constant.

def main():
 while True:
  loop_counter = loop_counter + 1
  if loop_counter % 2 == 0: function1()
  if loop_counter % 4 == 0: function2()
  if loop_counter % 10 == 0: function3()
  if loop_counter % 20 == 0: function4()
  #this assumes each loop take 0.5s to run

I'm new to python so any guidance is appreciated.

2
  • threading.Timer Commented Sep 5, 2022 at 15:42
  • schedule should be able to do this well. Commented Sep 5, 2022 at 15:45

2 Answers 2

4

You can use python schedule library. Docs here.

import schedule
def main():
  schedule.every(1).seconds.do(function1)
  schedule.every(2).seconds.do(function2)
  schedule.every(5).seconds.do(function3)
  schedule.every(10).seconds.do(function4)
  while True:
    schedule.run_pending()
    time.sleep(1)
Sign up to request clarification or add additional context in comments.

1 Comment

You have to do pip3 install schedule though
2

Using threading.Timer:

from threading import Timer
from time import monotonic


def run_every_n_secs(fn, n):
    start = monotonic()
    fn()
    elapsed = monotonic() - start
    Timer(n, lambda: run_every_n_secs(fn, max(n - elapsed, 0))).start()


def main():
    run_every_n_secs(function1, 1)
    run_every_n_secs(function2, 2)
    run_every_n_secs(function3, 5)
    run_every_n_secs(function4, 10)

Or if you don't mind having the same function running in parallel with itself (if e.g. function1 might take longer than a second to run but you want to start it every second anyway), you can start the timer for the next iteration before calling the function:

from threading import Timer

def run_every_n_secs(fn, n):
    Timer(n, lambda: run_every_n_secs(fn, n)).start()
    fn()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.