Python exiting multiple threads
Question: I'm trying to see how multi thread are working in order to use them in an
automation project. I can run the thread but I cannot find a way to exit
completely the two threads: the thread restart after each keyboard interupt.
Is there a way to exit both thread with a keyboard interupt ?

    
    
    import thread
    from time import sleep
    
    *parameters when starting
    temp_c = 32
    T_hot = 30
    T_cold = 27
    interval_temp = 2
    
    
    def ctrl_fan(temp_c, T_hot,interval_temp):
        while True:
            if temp_c >= T_hot:
                print 'refreshing'
            else:
                print ' fan stopped'
            sleep(interval_temp)
    
        print 'shutting everything off'
    
    
    def ctrl_light(temp_c, T_cold,interval_temp):
        while True:
            if temp_c <= T_cold:
                print 'warming'
            else:
                print 'light stopped'
            sleep(interval_temp)
    
        print 'shutting everything off'
    
    
    try:
        thread.start_new_thread(ctrl_fan, (temp_c, T_hot,interval_temp, ) )
    
        sleep(1)
    
        thread.start_new_thread(ctrl_light, (temp_c, T_cold,interval_temp, ) )
    except (KeyboardInterrupt, SystemExit):
        thread.exit()
        print "Error: unable to start thread"
    


Answer: Sure,

Firstly I'd recommend using the slightly higher level
[`threading`](https://docs.python.org/2/library/threading.html) module instead
of the `thread` module.

To start a thread with `threading` use the following

    
    
    import threading
    t = threading.Thread(target=ctrl_fan, args=(temp_c, T_hot, interval_temp))
    t.start()
    

There's a few things you'll need to do to get the program to exit with a
`Ctrl-C` interupt.

Firstly you will want to set the threads to be
[daemon](https://docs.python.org/2/library/threading.html#threading.Thread.daemon),
so that they allow the program to exit when the main thread exits (`t.daemon =
True`)

You will also want the main thread to wait on the completion of the threads,
you can use `t.join()` to do this. However this wont raise out a
`KeyboardInterrupt` exception until the thread finishes, there is a work
around for this though

    
    
    while t.is_alive():
        t.join(1)
    

Providing a timeout value gets around this.

I'd be tempted to pull this together into a subclass, to get the behaviour you
want

    
    
    import threading
    
    class CustomThread(threading.Thread):
        def __init__(self, *args, **kwargs):
            threading.Thread.__init__(self, *args, **kwargs)
            self.daemon = True
    
        def join(self, timeout=None):
            if timeout is None:
                while self.is_alive():
                    threading.Thread.join(self, 10)
            else:
                return threading.Thread.join(self, timeout)
    
    t1 = CustomThread(target=ctrl_fan, args=(temp_c, T_hot, interval_temp))
    t1.start()
    
    t2 = CustomThread(target=ctrl_light, args=(temp_c, T_cold, interval_temp))
    t2.start()
    
    t1.join()
    t2.join()
    

