5

標準ライブラリで遊んでいるときに、python2 と python3 の間に奇妙な違いがあることがわかりました。TCPServer が別のスレッドで実行されているときに python2 でシグナルをキャッチしようとすると、シグナルは処理されませんが、python3 では処理されます。

これは問題を再現するスクリプトです

import signal
import threading
import sys 
if sys.version_info > (3,0):
    from socketserver import TCPServer, BaseRequestHandler
else:
    from SocketServer import TCPServer, BaseRequestHandler

def shutdown(signum, frame):
    print("Shutting down server thread")
    server.shutdown()

server = TCPServer(
    ('127.0.0.1', 7654),
    BaseRequestHandler
)
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
server_thread = threading.Thread(target=server.serve_forever)
print("Starting server thread")
server_thread.start()
print("Waiting for server thread to shut down")
server_thread.join()
print("Server thread terminated")

これは python3 からの出力です:

Starting server thread
Waiting for server thread to shut down
^CShutting down server thread
Server thread terminated

そして、これはpython2からのものです:

Starting server thread
Waiting for server thread to shut down
^CKilled

"^C" はキーボード割り込みで、"Killed" はプロセスに送信した sigkill です。

シャットダウンが呼び出されなかったのはなぜですか?

4

1 に答える 1

4

私にとっては、 thread.join() がロックを作成し、シグナルをキャッチできないようです。

Python 2.7 で次のコードをテストしましたが、動作しているようです。

import time
import signal
import threading
import sys 
if sys.version_info > (3,0):
    from socketserver import TCPServer, BaseRequestHandler
else:
    from SocketServer import TCPServer, BaseRequestHandler

def shutdown(signum, frame):
    print("Shutting down server thread")
    server.running = False
    server.shutdown()

server = TCPServer(
    ('127.0.0.1', 7654),
    BaseRequestHandler
)
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
server_thread = threading.Thread(target=server.serve_forever)
print("Starting server thread")
server_thread.start()
server.running = True
print("Waiting for server thread to shut down")

while server.running:
    time.sleep(1)

server_thread.join()
print("Server thread terminated")
于 2012-06-07T07:58:08.610 に答える