2013-07-04 131 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是到流處理程序的引用。