2012-06-06 57 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")