2009-11-02 7 views
7

Aus irgendeinem Grund scheint siginterrupt() nur das Verhalten für das erste empfangene Signal einzustellen.siginterrupt() funktioniert nur für das erste Signal? (Python)

In diesem Beispielprogramm scheint das erste SIGQUIT nichts zu tun, aber das zweite sigquit gibt "SIGQUIT Handler" aus, und s.accept() löst eine unterbrochene Systemaufrufausnahme aus.

from signal import * 
from socket import * 
import sys 

def sigquitHandler(signum, frame): 
     print("SIGQUIT Handler") 

s = socket() 
s.bind(("0.0.0.0", int(sys.argv[1]))) 
s.listen(5) 

signal(SIGQUIT, sigquitHandler) 
siginterrupt(SIGQUIT, False) 

client, addr = s.accept() # Or any syscall that blocks 
client.close() 
s.close() 

Was missverstehe ich hier?


Edit: Hier ist etwas anderes, das ich nicht herausfinden kann, in diesem Programm ein SIGQUIT unterbricht die select(). Soll das passieren?

from signal import * 
import select 
import sys 

def sigquitHandler(signum, frame): 
    print("SIGQUIT Handler") 

signal(SIGQUIT, sigquitHandler) 
siginterrupt(SIGQUIT, False) 

select.select([sys.stdin], [], []) 
+1

Ich denke, dass 'siginterrupt' wirklich nur für Systemaufrufe gilt, dass die Übertragung von Daten (Primitiven wie Öffnen, Lesen oder Schreiben) beinhalten. Ich glaube nicht, dass es sich auf Systemaufrufe wie 'select' bezieht. – mhawke

+0

Ah, ok. Danke nochmal :) –

Antwort

2

Welche unix verwenden Sie? Auf der Ebene C gibt es verschiedene Implementierungen und Semantiken für die Signalverarbeitung auf BSD vs System 5 (SYSV).

Meine Vermutung ist, dass Sie SYSV verwenden, in diesem Fall wird die Signaldisposition auf SIG_DFL zurückgesetzt, nachdem der Signalhandler zurückgekehrt ist (klassische Signalbehandlung). Auf SYSV müssen Sie signal im Handler aufrufen, um diesen Handler neu zu installieren.

Python bietet mehr oder weniger BSD Stil Signalbehandlung. Auf einem SYSV-Betriebssystem muss Python die Neuinstallation des Signalhandlers über signal verwalten. Nun, nach dem doco Python für siginterrupt:

Beachten Sie, dass ein Signal-Handler mit Signal Installation() den Neustart Verhalten auf unterbrechbare von implizit Aufruf siginterrupt() mit ein echter Flag-Wert für das Zurücksetzen gegeben Signal.

Und los geht - wenn Python automatisch Signal-Handler neu zu installieren ist (BSD wie Semantik zur Verfügung zu stellen), kann es auch so in einer Weise tun, die implizit siginterrupt(1) aufruft.

Natürlich könnte meine Vermutung falsch sein.

Sie könnte Lage sein, dies zu beheben, indem sigquitHandler wie folgt definieren:

def sigquitHandler(signum, frame): 
    print("SIGQUIT Handler") 
    siginterrupt(SIGQUIT, False) 

Es hängt davon ab, wann und wie Python das Signal Anordnung wieder her.

EDIT

Hinzufügen siginterrupt(SIGQUIT, False) zum Signal-Handler hat keine Auswirkung.

EDIT 2

Nach etwas mehr um in dem python2.6 Quellcode Stossen es klar, dass dieses Problem nicht nur ein SYSV ist. Es wird auch BSD-Systeme beeinflussen.

+0

Das macht Sinn, danke! –

4

Es ist ein bug von Python."siginterrupt with flag = False wird zurückgesetzt, wenn das Signal empfangen wurde", was in der späteren Version von python2.6 behoben wurde. (2.6.6+, 2.7+)

Für die zweite beeinflusst siginterrupt select() nicht.

siehe http://lkml.org/lkml/2005/7/23/119