SocketServer ThreadingMixIn purpose of server_thread
Question: In the example of a asynchronous (threading) SocketServer
<http://docs.python.org/2/library/socketserver.html> a server thread (called
server_thread) is started, to start new threads for each request. Due to some
problems catching KeyboardInterrupts, I started looking for similar code and
found that there's no apparent difference when NOT using a server thread, but
ctrl-c actually works.

Even though my code works I'd very much like to know

1) Why does not a simple 'try' to catch KeyboardInterrupt work, when using the
server_thread?

2) What good does the server_thread from the example serve - as opposed to my
somewhat simpler example?

From the python SocketServer example, catching keyboardinterrupt in try does
not work:

    
    
    if __name__ == "__main__":
        server = ThreadedTCPServer(serverAddr, SomeCode)
    <snip>
        # Start a thread with the server -- that thread will then start one
        # more thread for each request
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.start()
    

My simpler example, ctrl-c works.

    
    
    if __name__ == "__main__":
        server = ThreadedTCPServer(serverAddr, SomeCode)
        try:
            server.serve_forever()
            print "ctrl-c to exit"
        except KeyboardInterrupt:
            print  "interrupt received, exiting"
            server.shutdown() 
    


Answer: 1) That's a general problem. When you do CTRL+C then a signal is sent to the
process. In the process the main thread catches the signal and (if not handled
properly) the main thread gets interrupted. But that signal does not kill
other threads. And Python won't quit as long as there are non-daemon threads
running (because that would not be safe). If you know what you are doing you
can add this:

    
    
    server_thread = threading.Thread(target=server.serve_forever)
    server_thread.daemon = True
    server_thread.start()
    

and it should work now (assuming you do something after
`server_thread.start()` like waiting - otherwise Python will just quit, it
won't wait for daemon threads). However remember that you may kill your server
during some important operation. In order to avoid that you should implement
some sort of graceful kill:

    
    
    import signal
    
    if __name__ == "__main__":
        server = ThreadedTCPServer(serverAddr, SomeCode)
    
        # some code
        server_thread = threading.Thread(target=server.serve_forever)
        server_thread.start()
        # some code
    
        try:
            signal.pause()  # wait for a signal, perhaps in a loop?
        except:
            server.shutdown()  # graceful quit
    

2) It just starts a server in a separate thread. Perhaps the idea was that you
can do other operations in the meantime? If you only want to run the server
there is no need to do that.

Also the reason might be the one I've stated above: graceful quit. If you just
interrupt the server it will die, perhaps during some important operation.

