2009-11-02 2 views
7

어떤 이유에서 siginterrupt()는 수신 된 첫 번째 신호의 동작을 설정하는 것처럼 보입니다.siginterrupt()는 첫 번째 신호에서만 작동합니까? (Python)

이 예제 프로그램에서 첫 번째 SIGQUIT는 아무 것도하지 않지만 두 번째 sigquit은 "SIGQUIT Handler"를 인쇄하고 s.accept()는 중단 된 시스템 호출 예외를 발생시킵니다.

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

여기 오해는 무엇입니까?


편집 : 여기이 프로그램에서 SIGQUIT이 select()를 인터럽트하는 다른 것을 알아 냈습니다. 그게 일어날 거니?

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

내가 siginterrupt' 정말 전용 데이터 (예 : 개방과 같은 원시, 읽기 또는 쓰기)의 전송을 포함하는 시스템 호출에 적용'생각을 참조하십시오. 'select'와 같은 시스템 호출에는 적용되지 않는다고 생각합니다. – mhawke

+0

아, 그래. 다시 한 번 감사드립니다 :) –

답변

2

어느 unix을 사용하고 있습니까? C 레벨에는 BSD vs System 5 (SYSV)에서 신호 처리를위한 다양한 구현과 의미가 있습니다.

내 생각에 SYSV를 사용하고 있는데,이 경우 신호 처리기가 반환 된 후 신호 처리가 SIG_DFL로 재설정됩니다 (클래식 신호 처리). SYSV에서 처리기를 다시 설치하려면 signal을 호출해야합니다.

파이썬은 BSD 스타일의 신호 처리 기능을 제공합니다. 따라서 SYSV OS에서, 파이썬은 signal을 통해 시그널 핸들러의 재설치를 관리해야합니다. 이제 siginterrupt에 대한 파이썬 DOCO에 따라 :

참고 에 대한 진정한 플래그 값 암시 적으로 호출 siginterrupt로()에 의해 인터럽트를 다시 시작 동작을 재설정) 신호 (의 신호 처리기 를 설치 주어진 신호.

그리고 거기 당신은 간다 - 파이썬은 자동으로 (의미 같은 BSD를 제공하기 위해) 당신의 신호 처리기를 다시 설치, 그것은 잘 암시 siginterrupt(1)를 호출하는 방법으로 그렇게 할 수있다 합니다.

물론 내 추측은 잘못되었을 수 있습니다.

당신

같은 sigquitHandler을 정의하여이 문제를 해결 할 수 있습니다 : 그것은 파이썬은 신호 처리를 복원 할 때와 방법에 따라 달라집니다

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

.

편집

전혀 영향을 미치지 신호 처리기에 siginterrupt(SIGQUIT, False) 추가.

편집 2

후 좀 더이 그냥 SYSV 문제가 아닙니다 분명히하는 Python2.6 소스 코드에 주위 파고. BSD 시스템에도 영향을줍니다.

+0

감사합니다. –

4

파이썬의 bug입니다."신호가 수신되면 flag = False로 siginterrupt가 초기화됩니다", 이는 python2.6 릴리스에서 수정되었습니다. (2.6.6+, 2.7+)

두 번째 경우 siginterrupt는 select()에 영향을주지 않습니다.

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

관련 문제