MLu
MLu

Reputation: 1370

How to kill python process that's using Timer()?

I've got a simple program with a function that's scheduled to run every 10 seconds using threading.Timer(). However I can't easily kill it with Ctrl+C - it keeps resisting and I have to ^C it multiple times to kill it. Here is my sample code that exhibits this behaviour:

#!/usr/bin/env python

import sys
import time
from threading import Timer

def scheduled_function():
    Timer(10, scheduled_function).start()

    print("Scheduled function called...\n")

if __name__ == "__main__":
    scheduled_function()

    try:
        while True:
            time.sleep(1)
    except KeyboardInterrupt:
        sys.exit(0)

And here is what happens when I run it and Ctrl+C it:

$ python timer.py 
Scheduled function called...

^C^C^C^C^CScheduled function called...

Exception KeyboardInterrupt in <module 'threading' from '/usr/lib/python2.7/threading.pyc'> ignored
Unhandled exception in thread started by 
sys.excepthook is missing
lost sys.stderr

Note how many times I had to use ^C to kill it. I guess it was waiting for the timer to expire and only then exitted.

Is there a clean way to catch KeyboardInterrupt and kill all the threads immediately?

Upvotes: 2

Views: 1713

Answers (1)

The first Ctrl-C did probably get to the exception handler. However, sys.exit(0) waits for all non-daemonic threads to exit. Timer is a subclass of thread, but it is not daemonic by default.

The solution is to make it a daemon, unfortunately it doesn't look as clean now

def scheduled_function():
    t = Timer(10, scheduled_function)
    t.daemon = True
    t.start()

With this change:

Scheduled function called...

^C
% 

Upvotes: 4

Related Questions