Константин
Константин

Reputation: 103

Run repeatedly two different functions every n seconds

I have two functions: foo() should start every 5 seconds and bar() should start every 10 seconds. code below:

import threading
import time


def foo():
    while True:
        time.sleep(5)
        print("Call every 5 seconds")
        time.sleep(5)

def bar():
    while True:
        time.sleep(10)
        print("Call every 10 seconds")


tr1 = threading.Thread(target=foo)
tr1.start()
tr2 = threading.Thread(target=bar)
tr2.start()

But I think that this is not a good solution. What is the best way to do this? And yes, I think that I have memory leak, should I use garbage collector or anything else?

P.S. I hope you could understand what i wrote, because I am not native speaker.

Upvotes: 0

Views: 411

Answers (2)

Bill Bell
Bill Bell

Reputation: 21643

Your code with minor changes, plus some print statements that suggest that this works alright. The 'good' thing about this code is that sleep will raise an exception if the argument to it is negative. Thus, if the codes expected to take less than five or ten seconds respectively take longer then then script will die.

import threading
import time
from datetime import timedelta, datetime

def foo(delay=5):
    while True:
        t_start = time.time()
        print("Call every %s seconds" % delay, datetime.now().strftime('%H.%M.%S'))
        t_end = time.time()
        time.sleep(delay-(t_end-t_start))

def bar(delay=10):
    while True:
        t_start = time.time()
        print("Call every %s seconds" % delay, datetime.now().strftime('%H.%M.%S'))
        t_end = time.time()
        time.sleep(delay-(t_end-t_start))

tr1 = threading.Thread(target=foo)
tr1.start()
tr2 = threading.Thread(target=bar)
tr2.start()

Here's the output.

>pythonw -u "temp1.py"
Call every 5 seconds 17.09.51
Call every 10 seconds 17.09.51
Call every 5 seconds 17.09.56
Call every 5 seconds 17.10.01
Call every 10 seconds 17.10.01
Call every 5 seconds 17.10.06
Call every 5 seconds 17.10.11
Call every 10 seconds 17.10.11
Call every 5 seconds 17.10.16
Call every 5 seconds 17.10.21
Call every 10 seconds 17.10.21
Call every 5 seconds 17.10.26
Call every 10 seconds 17.10.31
Call every 5 seconds 17.10.31
Call every 5 seconds 17.10.36

>Process failed to respond; forcing abrupt termination...
>Exit code: 1

I cannot say whether this is the 'best' way of doing this. At least the contents of the functions begin at more or less regular time intervals.

Upvotes: 0

Diego Amicabile
Diego Amicabile

Reputation: 589

Using the link posted by depperm in the comments

import sched, time
s = sched.scheduler(time.time, time.sleep)

def foo(s):
    print("Call every 5 seconds")
    s.enter(5, 1, foo, (s,))

def bar(s):
    print("Call every 10 seconds")
    s.enter(10, 1, bar, (s,))

s.enter(5, 1, foo, (s,))
s.enter(10, 1, bar, (s,))
s.run()

Upvotes: 1

Related Questions