简体   繁体   中英

Python SocketServer deadlock issue

When I'm threading the SocketServer instance (the serve_forever method) I can quit it easily when sending the text "shutdown", which is what I expect. However, if its not threaded then I run into the issue of it locking up and I can't figure out how to get around this.

The basic flow of the server itself is start->listen->get data->get the command from it->run the command (which is a plugin)->return the results. Here's the code I use:

import SocketServer as SS

NULL_RESP = {"status" : False, "data" : "No data received."}

class ASWCP_Daemon(SS.BaseRequestHandler):
    def handle(self):
        self.data = self.request.recv(1024).strip()

        if self.data == "":
           self.request.sendall(json.dumps(NULL_RESP))
           return None

       tmp = self.data.split(" ", 1)

       cmd = tmp[0]
       args = ""

       try:
           args = str(tmp[1]).split(conf.command_parse)
    except:
           pass

       plugin = plugins["cmd"][cmd]['ref'].init(conf=conf, socket=self)

       try:
           if args[0] == "help":
            self.request.sendall(plugin.help)
       except IndexError:
           status,data = plugin.run(args)
           resp = {"status" : status, "data" : data}
           self.request.sendall(json.dumps(resp))

  if __name__ == "__main__":
   # Log is created here; conf = config file (irrelevant to this issue)

   try:
       if conf.tcp:
           if conf.threaded:
               import threading
               class ThreadedTCPServer(SS.ThreadingMixIn, SS.TCPServer):
                   pass

               server = ThreadedTCPServer((conf.host, conf.listen_port), ASWCP_Daemon)
           else:
               server = SS.TCPServer((conf.host, conf.listen_port), ASWCP_Daemon)
       else:
           server = SS.UDPServer((conf.host, conf.listen_port), ASWCP_Daemon)

       if conf.threaded:
           sthread = threading.Thread(target=server.serve_forever)
           #sthread.daemon = True
           sthread.start()
       else:
           server.serve_forever()
   except KeyboardInterrupt:
       pass

The shutdown plugin's run method is this:

    def run(self, *args, **kwargs):
        if self.socket == None:
            print "> No socket available"
            return (False,"")
        else:
            self.socket.log.info("Shutting down daemon")
            self.socket.server.shutdown()

            return (True,"")

If threaded this is fine, if its not then it gets as far as the self.socket.server.shutdown() method in the plugin. self.socket is the instance of ASWCP_Daemon class.

    # Do shutdown() if threaded, else execute server_close()
    if self.sysconf.threaded:
        self.socket.server.shutdown()
    else:
        self.socket.server.server_close()

    return (True,"")

self.sysconf is the configuration for the daemon ( conf in the code in the question), and self.socket is a reference to the stream handler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM