3

I'm starting a simple TCP server using SocketServer:

class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
    pass
...
server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
server_thread = threading.Thread(target=server.serve_forever)
server_thread.daemon = True
server_thread.start()
try:
...
finally:
    server.shutdown()

However, after the program ends it doesn't terminate and seems to be stuck. It doesn't respond to keyboard events (CTRL-C) and the only way to exit is to call os._exit(0) or to just close the shell window.

I've searched a bit about it but I still don't see what I'm missing: The thread is marked as daemon, and the server is shut-down at the end.

I'm running Python 2.7.9 under Windows 8.1

Ben Morris
  • 606
  • 5
  • 24
Amir Gonnen
  • 3,525
  • 4
  • 32
  • 61
  • Did you try: `server_thread.join()` – Ozgur Vatansever Feb 05 '15 at 20:30
  • @ozgurv Good point. If the code reaches the end normally, it will terminate. However, if an exception is thrown (for example CTRL-C) it remains stuck with `server_thread.join()` (but not with `os._exit(0)`) – Amir Gonnen Feb 05 '15 at 20:53
  • Perhaps the server creates other internal threads and/or perhaps you need to call `server.server_close()` in addition to `server.shutdown()`. See: https://docs.python.org/2.7/library/socketserver.html#SocketServer.BaseServer.server_close – mpb May 11 '20 at 06:22

1 Answers1

0

Ctrl-c raises KeyboardInterrupt exception and the issue is SocketServer internally catches the error but never bothers to come out. You can add an extra signal handler for signal.SIGINT & then call server.start(). Like this,

import signal
import sys
def signal_handler(signal, frame):
     logger.log("DEBUG","You pressed Ctrl+C!")
     server.stop()
     sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
server_thread.start()
signal.pause()
  • This does not exactly work - it writes "You pressed Ctrl+C!" and remains stuck. But if I replace sys.exit(0) with os._exit(0) it does exit the application. Exiting with os._exit does not feel like a clean solution. – Amir Gonnen Feb 15 '15 at 21:41
  • 1
    and btw I think it's `server.shutdown()` not `server.stop()` – Amir Gonnen Feb 15 '15 at 21:43