在使用标准库时,我发现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.
为什么没有调用关机?
最佳答案
对我来说似乎thread.join()会产生一些锁定并阻止捕获信号.
我在Python 2.7中测试了以下代码,它似乎工作:
import time
import signal
import threading
import sys
if sys.version_info > (3,frame):
print("Shutting down server thread")
server.running = False
server.shutdown()
server = TCPServer(
('127.0.0.1',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")