2009-11-02 8 views
7

Z jakiegoś powodu siginterrupt() wydaje się tylko ustawić zachowanie dla pierwszego odebranego sygnału.siginterrupt() działa tylko dla pierwszego sygnału? (Python)

W tym przykładowym programie pierwszy SIGQUIT wydaje się nic nie robić, ale drugi sigquit wyświetla "SIGQUIT Handler", a s.accept() zgłasza wyjątek wywołania systemowego Przerwane.

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

Co tu nie rozumiem?


Edytuj: Oto coś innego, czego nie mogę zrozumieć, w tym programie SIGQUIT przerywa select(). Czy to ma się stać?

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

myślę, że 'siginterrupt' dotyczy naprawdę tylko wywołań systemowych, które dotyczą transferu danych (prymitywów takich jak otwarte, czytać i pisać). Nie sądzę, że dotyczy to wywołań systemowych, takich jak 'select'. – mhawke

+0

Ah, ok. Jeszcze raz dziękuję :) –

Odpowiedz

2

Którego użyjesz unix? Na poziomie C istnieją różne implementacje i semantyka obsługi sygnałów w systemie BSD w porównaniu z systemem 5 (SYSV).

Domyślam się, że używasz SYSV, w którym to przypadku rozkład sygnału jest resetowany do SIG_DFL po powrocie obsługi sygnału (klasyczna obsługa sygnału). W SYSV musisz zadzwonić pod numer signal w programie obsługi, aby ponownie zainstalować ten program obsługi.

Python mniej więcej zapewnia obsługę sygnałów w stylu BSD. Tak więc, w systemie SYSV OS, Python musi zarządzać ponowną instalacją obsługi sygnału poprzez signal. Teraz, zgodnie z doco Pythona do siginterrupt:

Należy pamiętać, że zainstalowanie obsługi sygnału z sygnału() spowoduje przywrócenie zachowania restart do ich przerwania niejawnie wywołującego siginterrupt() z prawdziwe wartości flag dla dany sygnał .

I nie udać - jeśli Python automatycznie ponowne zainstalowanie obsługi sygnału (aby zapewnić jak semantyki BSD), może być dobrze więc w sposób dorozumiany nazywa siginterrupt(1).

Oczywiście moje przypuszczenie może być błędne.

Ty może w stanie rozwiązać ten problem poprzez zdefiniowanie sigquitHandler tak:

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

To zależy od tego, kiedy i jak Python jest przywrócenie dyspozycję sygnału.

EDIT

Dodawanie siginterrupt(SIGQUIT, False) do obsługi sygnału nie ma wpływu.

EDIT 2

Po jakimś bardziej grzebać w kodzie źródłowym python2.6 to jasne, że nie jest to tylko problem SYSV. Wpłynie to również na systemy BSD.

+0

To ma sens, dzięki! –

4

To jest bug z Pythona."siginterrupt with flag = Fałsz jest resetowany, gdy sygnał został odebrany", który został naprawiony w późniejszym wydaniu python2.6. (2.6.6+, 2.7+)

Dla drugiego, siginterrupt nie wpływa na select().

zobaczyć http://lkml.org/lkml/2005/7/23/119

Powiązane problemy