如果TCPServer在另一个线程中运行,Python 2不处理信号

时间:2012-06-06 20:58:42

标签: python signals socketserver

在使用标准库时,我发现python2和python3之间存在一些奇怪的区别。如果我尝试在python2中捕获信号,而TCPServer在不同的线程中运行,则信号不会被处理,但是在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。

为什么没有调用shutdown?

1 个答案:

答案 0 :(得分: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")