2013-07-04 79 views
1

当我线程的SocketServer实例(serve_forever方法)时,我可以很容易地退出它发送文本“关机”,这是我所期望的。但是,如果它没有线程,那么我遇到了它锁定的问题,我无法弄清楚如何解决这个问题。Python的SocketServer死锁问题

服务器本身的基本流程是start-> listen-> get data->从它获取命令 - >运行命令(这是一个插件) - >返回结果。下面是我使用的代码:

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 

关机插件的run方法是这样的:

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,"") 

如果线程,这是好的,如果它不那么它会尽可能在插件中self.socket.server.shutdown()方法。 self.socket是ASWCP_Daemon类的实例。

+0

你能发布*完整*有问题的代码吗?这段代码没有正确缩进(只需从编辑器粘贴它,突出显示它,并在这里按'Ctrl + K'),'conf'没有被定义,并且它缺少实际的关闭,并且它包含不相关的代码进行线程化,因为禁用线程时会发生问题)。 – phihag

+0

对不起,真的很忙,所以没有机会回应。我修复了它,并将其作为答案。 –

回答

1
# 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用于守护进程(conf在问题的代码)的配置,并且self.socket是到流处理程序的引用。