トップ «前の日記 最新 次の日記»

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 で制御されてるから大丈夫だろうか…


編集 パスワード変更