title: sys.exit() not exiting in python
body: <p>I have a python2 program which uses <code>socket</code> and <code>SocketServer</code>. it basically consists of some clients, that can connect with each other.Each Client also has their own <code>Thread</code> which is implemented using <code>threading.Thread</code> and run in <code>daemon</code> mode. Now my problem is that when i call <code>sys.exit()</code> the program doesn't exit.I also (try to) close all open sockets before <code>sys.exit()</code> call.I also use <code>socket.makefile()</code> in the program, however I call <code>close</code> on all of the opened files right after I read from them.What could be the potential causes if <code>sys.exit()</code> not exiting?   </p>
  
  <p>Here's the code, the application is supposed to represent a graph of nodes,
  each node will contain an Edge to another node if we call <code>initiateConnection</code> on the first node with the address of the second one.Since the Edges are undirected I want both sides of the socket to be handled by the same <code>RequestHandler</code>.See notes above <code>Client.initiateConnection</code>.</p>
  
  <pre><code>import socket
  import SocketServer
  import select
  import sys
  import threading
  
  class Client(SocketServer.ThreadingTCPServer):
  
      """Attributes:
      neighbours: connections to neighbours
      n_addresses: addresses of Neighbours
      requests: Number of Requests Sent
      processed_requests:{}
      id: this client's id
      """
  
      def __init__(self, server_address, RequestHandlerClass, id):
          self.neighbours = []
          self.n_addresses = []
          self.requests = 0
          self.processed_requests = {}
          self.id = id
          SocketServer.ThreadingTCPServer.__init__(self, server_address, RequestHandlerClass)
  
      def initiateConnection(self, address):
          s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
          s.connect(address)
          self.neighbours.append(s)
          self.n_addresses.append(s.getpeername())
          self.addConnection(s, address)
          # check if the given port, and the connected one match
          if address[1] != s.getpeername()[1]:
              raise Exception(address, s.getpeername())
  
      """ this method is based on the _handle_request_no_block method on the base server
      we will add the connection created by this node i.e: this node is the client for that
      particular connection, to the list of connections handled by this server, i.e: view it as a server connection
      """
      #This method is supposed to add the request first instantiated by
      # the Client instance itself, to the requests the ThreadingTCPServer manages (creates a seperate thread for it and etc.)
      # Maybe there's something else I have to do, so that the ThreadingTCPServer closes this connection properly?
      def addConnection(self, request, address):
          if self.verify_request(request, address):
              try:
                  self.process_request(request, address)
              except:
                  self.handle_error(request, address)
                  self.shutdown_request(request)
  
      def addNeighbour(self, s):
          self.neighbours.append(s)
          self.n_addresses.append(s.getpeername())
  
      def server_close(self):
          print("{}: closing neighbours".format(self.id))
          for c in self.neighbours:
              print("{}: closing {}".format(c.getpeername()))
              c.close()
          print("{}: closed all neighbours".format(self.id))
          SocketServer.ThreadingTCPServer.server_close(self)
  
  
  class RequestHandler(SocketServer.StreamRequestHandler):
  
      GET_NEIGHBOURS="1"
      EOR="EOR"
      # the below function means someone is trying to initiate
      # connection, since it will be handled in it's own thread
      # we will initiate a loop and wait for a request.
      def handle(self):
          self.server.addNeighbour(self.request)
          while True:
              lines = []
              select.select([self.rfile], [], [])
              print("{}: got request from {}".format(self.server.id, self.request.getpeername()))
              while True:
                  line = self.rfile.readline().strip()
                  print("line read:\n{}".format(line))
                  if line == RequestHandler.EOR:
                      break
                  elif not bool(line):
                      continue
                  lines.append(line)
              print("{}: all request lines read:\n{}".format(self.server.id, lines))
              # we have a complete request now process it
              if lines[1] == self.GET_NEIGHBOURS:
                  print("{}: request was of type    get_neighbours".format(self.server.id))
                  data = self.processNeighbours(lines)
                  self.request.sendall("{}\n".format(data))
                  print("{}: data sent to {}".format(self.server.id, self.request.getpeername()))
  
  class UnknownRequestCode(Exception): pass
  
  if __name__ == '__main__':
  
      def output(s):
          print(s)
      def getLine():
          return sys.stdin.readline()
  
      address = ('', 0)
      clients = {}
      addresses = {}
      while True:
          print("commands:\nclose: exit\nnew: make a new client, will prompt for a client id\nshow: show a clients neighbours, will prompt for a client's id\nconnect: will connect a client to another one, will prompt for the ids")
          i = getLine().strip()
          if i == "close":
              for c in clients.values():
                  c.shutdown()
              print("everything shut down")
              sys.exit()
          if i == "new":
              i = getLine(). strip()
              client = Client(address, RequestHandler, i)
              clients[i] = client
              a = client.server_address
              addresses[i] = a
              output(a)
              t = threading.Thread(target=client.serve_forever)
              t.daemon = True
              t.start()
          elif i == "show":
              i = getLine().strip()
              c = clients[i]
              o = c.startSearch()
              #output(o)       
          elif i == "connect":
              i = getLine().strip()
              c = clients[i]
              i = getLine().strip()
              a = addresses[i]
              print("{}".format(a))
              c.initiateConnection(a)
  </code></pre>
  
  <p><strong>UPDATE</strong>: I have identified the (rather obvious) problem, the handle method never exits the loop since the nodes are always supposed to get connected, and wait for each other's request.But I can not check program termination since it gets stuck before the <code>select.select</code> call.How can I fix that?</p>