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類的實例。
你能發佈*完整*有問題的代碼嗎?這段代碼沒有正確縮進(只需從編輯器粘貼它,突出顯示它,並在這裏按'Ctrl + K'),'conf'沒有被定義,並且它缺少實際的關閉,並且它包含不相關的代碼進行線程化,因爲禁用線程時會發生問題)。 – phihag
對不起,真的很忙,所以沒有機會迴應。我修復了它,並將其作爲答案。 –