2022-03-02 (We) [長年日記]
_ python http.server の shutdown
#!/usr/bin/env python
import sys
import signal
import threading
import time
from http.server import HTTPServer, BaseHTTPRequestHandler
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
print('do_POST')
server = HTTPServer(('127.0.0.1', 8080), Handler)
def signaled(signal_number, frame):
print('SIGTERM, shutting down...')
server.shutdown()
print('done')
signal.signal(signal.SIGTERM, signaled)
print('starting')
server.serve_forever()
print('exit')
これを実行して kill コマンドで SIGTERM を送る。 すると、終了してくれない。
luna:~ % python test1.py
starting
SIGTERM, shutting down...
ここで止まってしまう。
ググりまくって、サンプルを見つけた。 以下のように修正した。
--- test1.py 2022-03-02 22:33:09.429720412 +0900
+++ test4.py 2022-03-02 22:33:04.005781546 +0900
@@ -19,5 +19,10 @@
signal.signal(signal.SIGTERM, signaled)
print('starting')
-server.serve_forever()
+#server.serve_forever()
+thread = threading.Thread(target=server.serve_forever)
+thread.daemon = True
+thread.start()
+thread.join()
+
print('exit')
すると、ちゃんと SIGTERM で終了するようになった。
luna:~ % python test4.py
starting
SIGTERM, shutting down...
done
exit
luna:~ %
ドキュメントをよく読むと…
shutdown()
Tell the serve_forever() loop to stop and wait until it
does. shutdown() must be called while serve_forever() is running
in a different thread otherwise it will deadlock.
別スレッドでやれよ、デッドロックするぞ、と書いてあった。
orz
んーしかし、本当は、既にマルチプロセスな作りなもので、 あんまりスレッドを使いたくないんだよねー。 それこそ意味不明なデッドロックになり兼ねないので。
Python は GIL で制御されてるから大丈夫だろうか…
[ツッコミを入れる]