2012-06-06 7 views
5

標準ライブラリで遊んでいるうちに、python2とpython3の間に奇妙な違いがあります。 TCPServerが別のスレッドで実行されているときに私がpython2でシグナルをキャッチしようとすると、シグナルは処理されませんが、python3ではシグナルが処理されます。TCPServerが別のスレッドで実行されている場合、Python 2はシグナルを処理しません

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 ^" ここ

は問題

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から出力された再現スクリプトがありますキーボードの割り込みで、 "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")