1

How to write a background thread in Python which will keep on calling a particular method every few minutes.

Let's say, if I am starting my program for the first time, then it should call that method right away, and after that, it should keep on calling that method every X minutes?

Is it possible to do in Python?

I don't have that much experience with Python threading. In Java I can use TimerTask or ScheduledExecutors for this problem but not sure how to do it with Python?

What's the best way to do this in Python?

3 Answers3

2

Use threading.Timer.

For example:

import threading

def print_hello():
    print('Hello')
    timer = threading.Timer(2, print_hello) # # Call `print_hello` in 2 seconds.
    timer.start()

print_hello()
falsetru
  • 357,413
  • 63
  • 732
  • 636
  • Somehow when I ran the above code, I see Hello got printed out twice, each after 2 seconds but after that it didn't printed out anything.. –  Jan 01 '14 at 06:11
  • @SSH, Sorry, I was wrong about `threading.Timer`. It only run the function only once. I updated the answer. – falsetru Jan 01 '14 at 06:12
  • Yeah. Now it works. Is there any purpose of using time.sleep(100) in the last line? –  Jan 01 '14 at 06:13
  • @SSH, Ah.. You don't need it. Removed it. – falsetru Jan 01 '14 at 06:14
0

I think this is a lot easier to do without trying to use Timer. Do it directly:

def my_background_task(seconds_between_calls):
    from time import sleep
    while keep_going:
        # do something
        sleep(seconds_between_calls)


...
from threading import Thread
t = Thread(target=my_background_task, args=(5*60,)) # every 5 minutes
keep_going = True
t.start()
...
# and when the program ends
keep_going = False
t.join()
Tim Peters
  • 67,464
  • 13
  • 126
  • 132
0

I've had good luck with this class. You would probably want to move the self.func() call before the time.sleep().

import threading
import time

class PeriodicExecutor(threading.Thread):

    def __init__(self, sleep, func, *params):
        'Execute func(params) every "sleep" seconds'
        self.func = func
        self.params = params
        self.sleep = sleep
        threading.Thread.__init__(self, name = "PeriodicExecutor")
        self.setDaemon(True)

    def run(self):
        while True:
            time.sleep(self.sleep)
#           if self.func is None:
#               sys.exit(0)
            self.func(*self.params)
dstromberg
  • 6,954
  • 1
  • 26
  • 27