2014-04-07 6 views
5

버전 정보를 기본으로 파이썬 SIGINT를 재설정신호 처리기를

  • OS : 윈도우 7
  • 파이썬 버전 3.3.5

아래는 내가 주위를 연주 된 테스트 코드의 작은 조각입니다. 특정 코드가 실행되는 동안 CTRL-C이 눌러 진 것을 무시하고 그 후에는 CTRL-C 동작이 복원됩니다. 이 놀아 동안 관찰 한 내용

import signal 
import time 

try: 
    # marker 1 
    print('No signal handler modifications yet') 
    print('Sleeping...') 
    time.sleep(10) 

    # marker 2 
    signal.signal(signal.SIGINT, signal.SIG_IGN) 
    print('Now ignoring CTRL-C') 
    print('Sleeping...') 
    time.sleep(10) 

    # marker 3 
    print('Returning control to default signal handler') 
    signal.signal(signal.SIGINT, signal.SIG_DFL) 
    print('Sleeping...') 
    time.sleep(10) 

except KeyboardInterrupt: 
    print('Ha, you pressed CTRL-C!') 

은 (예상)

  • CTRL-C 전송 2 마커 1 마커 사이 예외 핸들러에 의해 처리 될 것이다.
  • CTRL-C
  • 은 (예상대로 계속) 처리
  • CTRL-C마커 3 후 전송 무시되지만 3 마커 2 마커 사이 보낼 것이다 예외 핸들러에 있지 점프. 대신, 파이썬 은 즉시으로 종료됩니다. 또한

,이 사항을 고려하십시오

>>>import signal 

>>>signal.getsignal(signal.SIGINT) 
<built-in function default_int_handler> 

>>> signal.getsignal(signal.SIGINT) is signal.SIG_DFL 
False 

>>> signal.signal(signal.SIGINT, signal.SIG_DFL) 
<built-in function default_int_handler> 

>>> signal.getsignal(signal.SIGINT) is signal.SIG_DFL 
True 

을 그래서 처음에, 신호 처리기가 기본 신호 처리기로 간주되는 동안, SIG_DFL에 의해 정의 된 것과 다른 핸들러 것 같다.

누구나이 문제에 대해 밝힐 수 있다면 특히 예외 처리기가 신호 처리기를 SIG_DFL로 복원 한 후에 무시되는 경우가 있습니다.

+0

Windows에서 SIGINT에 문제가있는 경우 http : // stack을 참조하십시오. overflow.com/questions/16686510/how-do-i-capture-sigint-in-python-on-windows 및 http://bugs.python.org/issue18040 – cdarke

답변

7

KeyboardInterrupt 예외를 발생시키기 위해 파이썬은 자체 SIGINT 처리기를 설치합니다. 신호를 SIG_DFL으로 설정하면 핸들러가 복원되지 않고 시스템 자체의 "표준"핸들러 (인터프리터를 종료 함)가 복원됩니다.

from contextlib import contextmanager 

@contextmanager 
def sigint_ignored(): 
    original_sigint_handler = signal.getsignal(signal.SIGINT) 
    signal.signal(signal.SIGINT, signal.SIG_IGN) 
    try: 
     print('Now ignoring CTRL-C') 
     yield 
    except: 
     raise # Exception is dropped if we don't reraise it. 
    finally: 
     print('Returning control to default signal handler') 
     signal.signal(signal.SIGINT, original_sigint_handler) 

: kindall 정당 의견에 말했듯이

original_sigint_handler = signal.getsignal(signal.SIGINT) 

# Then, later... 
signal.signal(signal.SIGINT, original_sigint_handler) 

, 당신은 context manager으로 이것을 표현할 수있다 :이 완료되면

는 원래 핸들러를 저장하고 그 핸들러를 복원해야 다음과 같이 사용할 수 있습니다 :

# marker 1 
print('No signal handler modifications yet') 
print('Sleeping...') 
time.sleep(10) 

# marker 2 
with sigint_ignored(): 
    print('Sleeping...') 
    time.sleep(10) 

# marker 3 
print('Sleeping...') 
time.sleep(10) 
+3

컨텍스트 관리자로 일하는 것과 같습니다. – kindall

+2

기본 처리기는 항상 'signal.default_int_handler'로 사용할 수 있습니다. – eryksun

관련 문제