user1928167
user1928167

Reputation: 13

Stopping a timed thread in python

I'm trying to stop a thread in python when the main script is killed. But since the thread is started hourly how do i stop the thread immediately?

def interval():
    ###the actual work being done here###
    try:
        threading.Timer(3600, interval).start()
    except (KeyboardInterrupt, SystemExit):
        print "Exiting"
        cleanup_stop_interval();
        sys.exit()
interval()

Upvotes: 1

Views: 1203

Answers (3)

unutbu
unutbu

Reputation: 879113

You might consider using sched.scheduler instead of threading.Timer here. There are some differences to be aware of:

  • sched.scheduler runs everything in the main process, not in threads.
  • If the current process takes longer than delay seconds, the scheduled event will start after the current call to interval completes. threading.Timer works differently -- if the work done in interval takes longer than an hour, more than one thread would run interval concurrently.

I'm guessing you really do not want more than one interval to be running concurrently, so sched.scheduler may be more appropriate here than threading.Timer.


import timeit
import sched
import time
import logging
import sys

logger = logging.getLogger(__name__)
logging.basicConfig(level = logging.DEBUG,
                    format = '%(threadName)s: %(asctime)s: %(message)s',
                    datefmt = '%H:%M:%S')
schedule = sched.scheduler(timeit.default_timer, time.sleep)
delay = 5 # change to 3600 to schedule event in 1 hour

def interval():
    logger.info('All work and no play makes Jack a dull boy.')
    schedule.enter(delay = delay, priority = 1, action = interval, argument = ())
    # Uncomment this to see how scheduled events are delayed if interval takes a
    # long time. 
    # time.sleep(10) 

schedule.enter(delay = 0, priority = 1, action = interval, argument = ())
try:
    schedule.run()
except (KeyboardInterrupt, SystemExit):
    print('Exiting')
    sys.exit()

Upvotes: 2

Ned Batchelder
Ned Batchelder

Reputation: 375484

You can't stop a thread from another thread. What you probably want is to make the thread a daemon thread, meaning the process will exit even if the thread is still active:

http://docs.python.org/2/library/threading.html#threading.Thread.daemon

daemon

A boolean value indicating whether this thread is a daemon thread (True) or not (False). This must be set before start() is called, otherwise RuntimeError is raised. Its initial value is inherited from the creating thread; the main thread is not a daemon thread and therefore all threads created in the main thread default to daemon = False.

The entire Python program exits when no alive non-daemon threads are left.

Note you could still have problems where the process ended in the middle of this thread doing its work. If you want to protect against that, then have the thread wake up frequently to check if it should exit cleanly.

Upvotes: 0

mSolujic
mSolujic

Reputation: 156

It is a bad idea to kill a thread just like that, cause it could

  • holding resources
  • be a parent to other threads

proper way of handling this is to have an exit_request flag that each threads checks on regular interval to see if it is time for him to exit, and wait for it to exit by using join()

Upvotes: 2

Related Questions