BackType Technology

Stuff we're using / building 
« Back to blog

Forcing the process to exit in a multithreaded Python program

I was recently working on a Python daemon that consisted of a few worker threads. The workers interacted with the internet and I wanted the whole process to die if any thread hit an error. You might think the following would work:

  def mythread(): 
    try: 
      do_work() 
    catch Exception, e: 
      sys.exit(1) 
 

Unfortunately, you would be mistaken. sys.exit actually just raises the "SystemExit" exception - which means that one thread will die and the rest of the program will continue humming along.

There's a couple other Python methods you might try to use. os.abort() will cause the program to die but in a really ugly way. When I try it on my Mac the program exits with "Abort Trap" and I get one of those dialogs saying that Python quit unexpectedly. There's also an os._exit method which does what we want, but the docs say only to use it to kill child processes that have been forked.

Here's a good pattern to use to ensure your process cleanly dies whenever a thread dies:

 workers = [Thread(...), Thread(...), Thread(...)]
 for worker in workers:
   worker.setDaemon(True)
   worker.start()
 
 while True:
   for worker in workers:
     if not worker.isAlive():
       sys.exit(1)
   time.sleep(10)
 

A program will exit when the only threads remaining are "daemon" threads (the main thread is a non-daemon thread). The structure of this template pushes all work in worker daemon threads, and the main thread simply wakes up periodically to check if any of the workers have died. If so, the main thread exits which will cause the process to exit properly.

Loading mentions Retweet
Posted by Nathan Marz 

Comments (0)

Leave a comment...

 
Got an account with one of these? Login here, or just enter your comment below.
Posterous-login    twitter