I have python code which runs continuously (collecting sensor data). It is supposed to be launched at boot using start-stop-daemon
. However, I'd like to be able to kill the process gracefully, so I've started from the advice in the post How to process SIGTERM signal gracefully? and put my main loop in a separate thread. I'd like to be able to gracefully shut it down both when it is running as a daemon (the start-stop-daemon
will send a kill signal) and when I launch it briefly for testing in a terminal myself (me pressing ctrl-c
).
However, the signal handler doesn't seem to be called if I kill the process (even without using the thread, the "done (killed)
" never ends up in the file I've redirected to). And when I press ctrl-c
, the collecting just continues and keeps printing data in the terminal (or to the file I am redirecting to).
What am I doing wrong in the following code?
from threading import Thread
import time, sys, signal
shutdown_flag = False #used for gracefull shutdown
def main_loop():
while not shutdown_flag:
collect_data() # contains some print "data" statements
time.sleep(5)
print "done (killed)"
def sighandler(signum, frame):
print 'signal handler called with signal: %s ' % signum
global shutdown_flag
shutdown_flag = True
def main(argv=None):
signal.signal(signal.SIGTERM, sighandler) # so we can handle kill gracefully
signal.signal(signal.SIGINT, sighandler) # so we can handle ctrl-c
try:
Thread(target=main_loop, args=()).start()
except Exception, reason:
print reason
if __name__ == '__main__':
sys.exit(main(sys.argv))
You are terminating your main thread with this statement:
So your signal handler never gets to run. The signal handler is part of the main thread not the
main_loop
thread you created. So once the main thread exits there's no signal handler function to call anymore.You need something like this:
A simple test to see how many threads are running in your program is this: