免責事項: 私は 0、nil、null、none、python の経験がありません。
免責事項2:私は、あなたのサーバーが「行くべき道」であるとは決して思いません...サーバーに関連するものはすべて、最も基本的なことや学校の宿題以外のものでさえありません。人々が基本を学ぶのに役立つ良いサンプルかもしれませんが、同時に、私が数え切れないほど多くのレベルで誤解を招き、間違っています.
あなたの問題に戻ります。私はあなたのコードを取り、意図したとおりに動作するように修正しました:
#!/usr/bin/python
import signal
import SocketServer
import threading
import thread
class DummyServer(SocketServer.BaseRequestHandler):
def handle(self):
data = self.request.recv(1024)
self.request.send(data)
return
def shutdownHandler(msg,evt):
print "shutdown handler called. shutting down on thread id:%x"%(id(threading.currentThread()))
server.shutdown()
print "shutdown complete"
evt.set()
return
def terminate(signal,frame):
print "terminate handle on thread id:%x"%(id(threading.currentThread()))
t = threading.Thread(target = shutdownHandler,args = ('SIGTERM received',doneEvent))
t.start()
if __name__ == "__main__":
doneEvent = threading.Event()
print "main thread id:%x"%(id(threading.currentThread()))
signal.signal(signal.SIGTERM, terminate)
server = SocketServer.TCPServer(("localhost",9999), DummyServer)
server.serve_forever()
doneEvent.wait()
SocketServer のコード、特に server_forever() および shutdown() メソッドを確認する必要があります。また、スレッドについて、およびそれらの間であらゆる種類の通信/シグナリングを行う方法を学ぶようにしてください。これらのトピックに関する優れたソースがたくさんあります。
スレッドについて覚えておくべき基本的なことは、一般的に言えば、スレッドは一度に 1 つのことしかできないということです。シグナル ハンドラーはそれらの例外の 1 つです :) スレッドが server_forever() でスタックしている場合、 shutdown() への呼び出しも実行できるように同じスレッド。Python (シグナルのドキュメントを確認してください) は、シグナル ハンドラーをメイン スレッドで実行します。これは、コードから server_forever() ループを実行するのと同じスレッドです。シグナル ハンドラー内から shutdown() を呼び出すと、デッドロックが発生します。
これを回避するには、shutdown() を実行するためだけに新しいスレッドを作成します。新しいスレッドの shutdown() 呼び出しは、メイン スレッドの server_forever() に、ループを中断して終了する時間であることを知らせます。メイン スレッドは、shutdown() を実行しているスレッドが完了する前に終了することさえあります。
doneEvent は、シャットダウン スレッドが完了するまでメイン スレッド (doneEvent.wait()) が待機することを確認するために存在します。終了する前に「shutdown complete」を出力します。