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

标签 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。

为什么没有调用关机?

最佳答案

对我来说,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")

关于如果 TCPServer 在另一个线程中运行,Python 2 不处理信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10922192/

相关文章:

python - 如何在Python中过滤文本文件第一行中的字段名

python - 测试 Pandas 系列中的值是否在数组中

python - 模块 'cv2.cv2' 没有属性 'ximgproc'

bash - 如何将自定义信号发送到 bash 守护进程?

python - 我应该使用哪个 Python 库? SocketServer 还是 Asyncio?

python - 在 Python 中,是否可以在一个表达式中将列表拆分为第一个、内部和最后一个元素?

python - python 如何在 os.system ("sleep..."时阻塞信号)?

linux - sigreturn 如何在 SECCOMP_SET_MODE_STRICT 中阻止除 SIGKILL 和 SIGSTOP 之外的所有信号?

python - 单击按钮时运行 Python 脚本

python - SocketServer rfile.read() 非常非常慢