2009-11-02 10 views
7

किसी कारण से, siginterrupt() केवल प्राप्त पहली सिग्नल के लिए व्यवहार सेट करने लगता है।siginterrupt() केवल पहले सिग्नल के लिए काम करता है? (पायथन)

इस उदाहरण प्रोग्राम में, पहला सिग्क्विट कुछ भी नहीं करता है, लेकिन दूसरा सिग्क्विट प्रिंट "सिग्क्विट हैंडलर" और एस। एसेप्ट() एक बाधित सिस्टम कॉल अपवाद फेंकता है।

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 चयन व्यवधान()। क्या ऐसा होनेवाला है?

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' वास्तव में केवल सिस्टम कॉल कि डेटा (जैसे खुले रूप में पुरातन, पढ़ना या लिखना) के हस्तांतरण को शामिल करने के लिए लागू होता है देखते हैं। मुझे नहीं लगता कि यह 'चयन' जैसी सिस्टम कॉल पर लागू होता है। – mhawke

+0

आह, ठीक है। धन्यवाद फिर से :) –

उत्तर

2

कौन सा unix आप उपयोग कर रहे हैं? C स्तर पर, बीएसडी बनाम सिस्टम 5 (SYSV) पर सिग्नल हैंडलिंग के लिए विभिन्न कार्यान्वयन और अर्थशास्त्र हैं।

मेरा अनुमान है कि आप SYSV का उपयोग कर रहे हैं, सिग्नल हैंडलर लौटने के बाद सिग्नल स्वभाव को SIG_DFL पर रीसेट कर दिया गया है (क्लासिकल सिग्नल हैंडलिंग)। SYSV पर आपको हैंडलर को पुनर्स्थापित करने के लिए हैंडलर में signal पर कॉल करने की आवश्यकता है।

पायथन अधिक या कम बीएसडी शैली सिग्नल हैंडलिंग प्रदान करता है। तो, एक एसवाईएसवी ओएस पर, पायथन को signal के माध्यम से सिग्नल हैंडलर की पुनर्स्थापन का प्रबंधन करना होगा। अब, siginterrupt के लिए अजगर doco के अनुसार:

ध्यान दें कि संकेत (के साथ एक संकेत हैंडलर ) स्थापित करने के लिए एक सच्चे झंडा मूल्य के साथ परोक्ष बुला siginterrupt() द्वारा व्यवधान कारक को पुनः आरंभ व्यवहार को रीसेट कर देगा संकेत दिया गया।

और वहाँ तुम जाओ - अगर पायथन स्वचालित रूप से अपने संकेत हैंडलर फिर से स्थापित करने की जाती है (अर्थ विज्ञान की तरह बीएसडी प्रदान करने के लिए), यह अच्छी तरह से एक तरीका है कि परोक्ष siginterrupt(1) कॉल में ऐसा करने से हो सकता है।

बेशक, मेरा अनुमान गलत हो सकता है।

आप इस तरह sigquitHandler को परिभाषित करते हुए इसे ठीक करने में सक्षम हो सकता:

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

यह कब और कैसे अजगर संकेत स्वभाव पुनर्स्थापित कर रहा है पर निर्भर करता है।

संपादित

संकेत हैंडलर नहीं को प्रभावित किया है करने के लिए siginterrupt(SIGQUIT, False) जोड़ा जा रहा है।

संपादित 2

के बाद कुछ और python2.6 स्रोत कोड में चारों ओर poking यह स्पष्ट है कि यह सिर्फ एक SysV मुद्दा नहीं है। यह बीएसडी सिस्टम को भी प्रभावित करेगा।

+0

यह समझ में आता है, धन्यवाद! –

4

यह पाइथन के bug है।"ध्वज के साथ siginterrupt = संकेत प्राप्त होने पर गलत है रीसेट किया गया है", जो बाद में python2.6 रिलीज में तय किया गया है। (2.6.6+, 2.7+)

दूसरे के लिए, siginterrupt चयन() को प्रभावित नहीं करता है।

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

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