2014-04-07 8 views
5

संस्करण जानकारी:अजगर SIGINT रीसेट संकेत हैंडलर डिफ़ॉल्ट

  • ओएस: विंडोज 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 अपवाद संचालक द्वारा कार्रवाई की जाएगी (उम्मीद के रूप में)।
  • CTRL-C भेजा मार्कर और के बीच 2मार्कर 3 नजरअंदाज कर दिया है (अब भी, उम्मीद के रूप में)
  • CTRL-Cमार्कर 3 के बाद भेजा संसाधित किया जाता है, लेकिन होगा अपवाद संचालक के लिए नहीं कूद। इसके बजाय, पायथन सिर्फ तुरंत समाप्त हो जाता है।

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

विंडोज़ पर सिगिनट के साथ समस्याएं हैं, http: // स्टैक देखें overflow.com/questions/16686510/how-do-i-capture-sigint-in-python-on-windows और http://bugs.python.org/issue18040 – cdarke

उत्तर

7

पायथन अपवाद बढ़ाने के लिए अपने 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) 

:

original_sigint_handler = signal.getsignal(signal.SIGINT) 

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

kindall हक टिप्पणी में कहते हैं, आप एक 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

संबंधित मुद्दे