2015-06-27 5 views
6

So können, sage ich diesen Code haben:python - Fangen Signale zwischen Schlaf ruft

import signal 
from time import sleep 

def signalHandler(sig, frame): 
    print "signalHandler" 
    while True: 
     sleep(1) 
     #print "Caught" # Uncomment this line, and you get multiple signals - commented, you don't. 

signal.signal(signal.SIGINT, signalHandler) 
while True: 
    sleep(1) 

Wie im Kommentar zu sehen, wenn die print-Anweisung unkommentiert ist, funktioniert der Code normalerweise, und das Signal Handler fangen Jedes nachfolgende CTRL-C drückt wie es sollte. Wenn sie jedoch kommentiert wird, wird niemals ein anderes Signal abgefangen.

Warum ist das? Meine Vermutung ist, dass aufeinanderfolgende Schlafanrufe zusammengemischt werden und die Kontrolle nie wieder bei Python ankommt, um ein Signal zu bekommen. Was müsste es für eine Druckanweisung tun. Kann jemand Einblick in das geben?

+0

Haben Sie versucht, eine 'signal.pause()' hinzuzufügen? Was versuchst du eigentlich? –

+0

Ich versuchte, mehrere CTRL-C-Druckmaschinen zu verarbeiten, und bemerkte dieses Verhalten. Glücklicherweise konnte ich mein Problem mit 'Signal.signal (Signal.SIGINT, Signal.SIG_IGN)' lösen, da das Ignorieren einer anderen CTRL-C-Druckmaschine für mich gut funktioniert. Ich bin nur verwirrt, was Schlaf macht, der das Signal nicht mehr registrieren lässt. – westem

Antwort

1

Das ist in der Tat seltsam!

Ich glaube, das ist eine subtile Interaktion zwischen den Interna des von Python generierten Bytecodes und einer in Python 2.7 vorhandenen Anomalie. Beachten Sie zwei Dinge:

  • Ihr Code funktioniert perfekt in Python 3 mit oder ohne die print-Anweisung.
  • Wenn Sie den Schlaf im Signalhandler in "Schlaf (60)" ändern, werden Sie feststellen, dass es noch funktioniert, wenn Sie STRG-C drücken, bevor der Druck sogar erreicht wird! (Das hat mich verdächtig gemacht).

Wenn Sie Issue 12472 in the Python bug tracker lesen, werden Sie sehen, dass Python einen internen Anruf zu Py_CheckSleepvor die nächste Anweisung fügt (in diesem Fall den Druck), die das Signal verursacht gefangen werden, wenn der Schlaf unterbrochen wird, . Ohne den Druck erfolgt keine zusätzliche Prüfung.

Laut dem Problem wurde dies in Python 3 und höher behoben, aber nicht in früheren Versionen.