2012-06-06 22 views
5

使用标准库时,我发现python2和python3之间存在一个奇怪的区别。如果我尝试在python2中捕获信号,而TCPServer在另一个线程中运行,则信号不会得到处理,但是在python3中它会处理。如果TCPServer在另一个线程中运行,Python 2无法处理信号

这里是能重现问题

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。

为什么关闭不被调用?

+0

你如何发送SIG_INT信号的过程? – Tisho

+0

@Tisho在POSIX系统中,Control-C导致活动程序收到一个SIGINT信号。 [wiki](http://en.wikipedia.org/wiki/Control-C#In_command-line_environments) – Blin

+0

好的,至少我们知道SIGKILL信号的作用。如果你绑定SIGKILL关闭,它会起作用吗? – Tisho

回答

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")