2012-06-06 7 views
5

Während ich mit der Standard-Bibliothek spiele, habe ich einen seltsamen Unterschied zwischen python2 und python3 gefunden. Wenn ich versuche, ein Signal in python2 abzufangen, während TCPServer in einem anderen Thread läuft, wird das Signal nicht behandelt, aber in python3 tut es das.Python 2 behandelt keine Signale, wenn TCPServer in einem anderen Thread läuft

Hier ist ein Skript, das das Problem

Dies ist die Ausgabe von 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") 

reproduziert:

Starting server thread 
Waiting for server thread to shut down 
^CShutting down server thread 
Server thread terminated 

Und das ist von python2:

Starting server thread 
Waiting for server thread to shut down 
^CKilled 

"^ C" ist ein Tastatur-Interrupt und "Killed" ist sigkill, das ich an einen Prozess gesendet habe.

Warum wurde das Herunterfahren nicht aufgerufen?

+0

Wie beurteilen Sie das SIG_INT Signal an den Prozess senden? – Tisho

+0

@Tisho in POSIX-Systemen bewirkt Control-C, dass das aktive Programm ein SIGINT-Signal empfängt. [wiki] (http://en.wikipedia.org/wiki/Control-C#In_command-line_environments) – Blin

+0

Ok, zumindest wir wissen, SIGKILL Signal funktioniert. Wenn Sie SIGKILL zum Herunterfahren binden, wird es funktionieren? – Tisho

Antwort

4

Für mich scheint thread.join() macht eine Sperre und verhindert das Abfangen des Signals.

Ich habe den folgenden Code in Python 2.7 getestet und es scheint zu funktionieren:

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