क्या संकेत को अनदेखा किया जा सकता है (खो)?


9

मेरे पास एक एप्लिकेशन है जो सिग्नल के माध्यम से श्रमिकों के साथ संवाद कर रहा है (particullary SIGUSR1 / SIGUSR2 / SIGUSOP)।

क्या मैं भरोसा कर सकता हूं कि जो कुछ भी होता है वह हर सिग्नल हैंडलर द्वारा वितरित और संसाधित किया जाएगा।

यदि संकेतों को त्वरित रूप से भेजा जाता है तो क्या होता है जो उन्हें संभालने के लिए संभव नहीं है (जैसे कि इस समय उच्च होस्ट लोड के कारण)?

जवाबों:


8

"बहुत अधिक संकेतों" समस्या के अलावा, संकेतों को स्पष्ट रूप से अनदेखा किया जा सकता है। से man 2 signal:

If the signal signum is delivered to the process, then one of the
following happens:    
  *  If the disposition is set to SIG_IGN, then the signal is ignored.

सिग्नल भी अवरुद्ध हो सकते हैं। से man 7 signal;

A signal may be blocked, which means that it will not be delivered
until it is later unblocked.  Between the time when it is generated
and when it is delivered a signal is said to be pending.

संकेतों की अवरुद्ध और नजरअंदाज किए गए दोनों सेटों को बाल प्रक्रियाओं द्वारा विरासत में मिला है, इसलिए ऐसा हो सकता है कि आपके आवेदन की मूल प्रक्रिया ने इन संकेतों में से किसी एक को अनदेखा या अवरुद्ध कर दिया हो।

जब प्रक्रिया पिछले लोगों को संभालने से पहले कई सिग्नल वितरित करती है तो क्या होता है? जो कि OS पर निर्भर करता है। signal(2)उपरोक्त लिंक किया गया मेन्यू इस पर चर्चा करता है:

  • सिस्टम V डिफ़ॉल्ट रूप से सिग्नल डिस्पोज़ को रीसेट करेगा। इससे भी बदतर, कई संकेतों के तेजी से वितरण के परिणामस्वरूप पुनरावर्ती (?) कॉल आएंगे।
  • हैंडलर होने तक बीएसडी अपने आप सिग्नल को ब्लॉक कर देगा।
  • लिनक्स पर, यह जीएनयू के लिए निर्धारित संकलन झंडे पर निर्भर करता है libc, लेकिन मुझे बीएसडी व्यवहार की उम्मीद है।

4
लिनक्स का मैन पेज signal(2)सशक्त रूप से बताता है कि आप sigaction(2)इसके बजाय इस भ्रम से बचते हैं ।
नैट एल्ड्रेडज

7

आप भरोसा नहीं कर सकते कि भेजे गए हर सिग्नल को वितरित किया जाएगा। उदाहरण के लिए, लिनक्स कर्नेल "SIGCHLD" का सहवास करता है यदि किसी प्रक्रिया को किसी पूर्व चाइल्ड प्रक्रिया से SIGCHLD को संभालने में लंबा समय लगता है।

आपके प्रश्न के एक अन्य भाग का उत्तर देने के लिए, कर्नेल के अंदर सिग्नल "कतारबद्ध" हो जाते हैं यदि कई सिग्नल बहुत कम अंतराल में आते हैं।

आपको सदस्य के sigaction()साथ सिग्नल हैंडलर सेट करने के लिए उपयोग करना चाहिए , तर्क के सदस्य को ध्यान से सेट करना चाहिए । मुझे लगता है कि इसका मतलब है कम से कम "asynch" संकेतों के सभी मास्किंग। लिनक्स के लिए मैन पेज के अनुसार , आप सिग्नल को संभाले जाने से बच जाएंगे। मुझे लगता है कि आपको सदस्य को SA_SIGINFO में सेट करना चाहिए , लेकिन मुझे याद नहीं है कि मेरे पास यह अंधविश्वास क्यों है। मेरा मानना ​​है कि यह आपकी प्रक्रिया को एक सिग्नल हैंडलर मिलेगा जो बिना किसी दौड़ की स्थिति के साथ सेट होता है, और एक जो अन्य अधिकांश संकेतों से बाधित नहीं होता है।sa_sigactionsiginfo_tsa_masksiginfo_tsigaction()sa_flags

अपने सिग्नल हैंडलर फ़ंक्शन को बहुत सावधानी से लिखें। मूल रूप से यह संकेत करने के लिए एक वैश्विक चर निर्धारित किया है कि एक संकेत पकड़ा गया, और उस संकेत के लिए वांछित कार्रवाई के साथ बाकी प्रक्रिया सौदा है। इस तरह से कम से कम समय के लिए सिग्नल मास्क किए जाएंगे।

इसके अलावा, आप अपने सिग्नल हैंडलिंग कोड का बहुत अच्छी तरह से परीक्षण करना चाहेंगे। इसे एक छोटी परीक्षण प्रक्रिया में रखें और संभव के रूप में कई SIGUSR1 और SIGUSR2 संकेतों को भेजें, शायद 2 या 3 विशेष उद्देश्य सिग्नल भेजने वाले कार्यक्रमों से। कुछ अन्य संकेतों में भी मिक्स करें, जब आप आश्वस्त हों कि आपका कोड SIGUSR1 और SIGUSR2 को तेजी से और सही तरीके से संभाल सकता है। कठिन डिबगिंग के लिए खुद को तैयार करें।

यदि आप linux और only linux का उपयोग कर रहे हैं, तो आप signalfd()एक फाइल डिस्क्रिप्टर बनाने के लिए उपयोग करने के बारे में सोच सकते हैं जिसे आप select()प्राप्त कर सकते हैं या उन संकेतों को प्राप्त करने के लिए मतदान कर सकते हैं। उपयोग signalfd()करना डिबगिंग को आसान बना सकता है।


2
यह केवल SIGCLD नहीं है, जो तराशा जाता है: यदि वे संसाधित किए जा सकते हैं तो सभी संकेत संभावित रूप से वितरित किए जाते हैं।
गिल्स एसओ- बुराई को रोकें '

क्या SIGCHLD संकेतों के लिए "बहुत लंबा" का कोई माप है? मैं अभी अपने कार्यक्रम में इस व्यवहार का अनुभव कर रहा हूं, और मेरा सिग्नल हैंडलर ~ 100ms से अधिक नहीं लेता है, जो मैं बताऊंगा।
xrisk

@ ऋषव - मेरे ज्ञान में यह पता लगाने का कोई तरीका नहीं है कि "बहुत लंबा" क्या है। मैं उम्मीद करूंगा कि समग्र प्रणाली भार महत्वपूर्ण है। यही है, जो अन्य प्रक्रियाएं और कर्नेल कर रहे हैं, उनके लिए संकेतों के बीच "कब तक" को प्रभावित करने के लिए सहवास करना होगा। एक उपयोगी उत्तर नहीं, मुझे लगता है।
ब्रूस एडिगर

6

एक सिग्नल को डिलीवर करने की गारंटी दी जाती है, इस अर्थ में कि यदि कोई प्रक्रिया सफलतापूर्वक कॉल करती है kill, तब लक्ष्य को संकेत प्राप्त होगा। यह अतुल्यकालिक है: प्रेषक को यह पता करने का कोई तरीका नहीं है कि संकेत कब प्राप्त होता है या संसाधित होता है। हालांकि, यह गारंटी नहीं देता है कि सिग्नल दिया जाएगा। सिग्नल को संसाधित करने से पहले लक्ष्य मर सकता है। यदि लक्ष्य वितरित होने के समय संकेत की अनदेखी कर रहा है, तो संकेत का कोई प्रभाव नहीं होगा। यदि लक्ष्य एक ही संकेत संख्या के कई उदाहरण प्राप्त करता है इससे पहले कि यह उन्हें संसाधित कर सके, तो संकेत (और आमतौर पर) विलय हो सकते हैं: यदि आप एक ही संकेत को दो बार एक प्रक्रिया में भेजते हैं, तो आप यह नहीं जान सकते हैं कि प्रक्रिया संकेत प्राप्त करेगी या नहीं एक या दो बार। सिग्नल ज्यादातर एक प्रक्रिया को मारने के लिए डिज़ाइन किए जाते हैं या एक प्रक्रिया को ध्यान देने के तरीके के रूप में, वे संचार के लिए डिज़ाइन नहीं किए जाते हैं।

यदि आपको विश्वसनीय वितरण की आवश्यकता है तो आपको एक अलग संचार तंत्र की आवश्यकता है। प्रक्रियाओं के बीच दो मुख्य संचार तंत्र हैं: एक पाइप अप्रत्यक्ष संचार की अनुमति देता है; एक सॉकेट द्विदिश संचार और एक ही सर्वर के कई कनेक्शन की अनुमति देता है। यदि आपको लक्ष्य के रूप में कई अधिसूचनाओं को संसाधित करने की आवश्यकता है, तो आप इसे एक पाइप पर बाइट्स भेजते हैं।


4
क्या आपको लिखने का मतलब है "एक संकेत दिया जाने की गारंटी है" जब से आप कुछ तरीकों का वर्णन करने के लिए आगे बढ़े, जिसमें संकेत वितरित नहीं किया जाएगा (यानी प्रक्रिया प्राप्त होने से पहले ही मृत्यु हो गई थी, या संकेत coalesced थे)?
जॉनी

2

कर्नेल मानक संकेतों को समाहित करने के लिए स्वतंत्र है यदि एक से अधिक वितरित अवरुद्ध होने पर वितरित किया जाता है। दूसरी ओर वास्तविक समय के संकेत इसी तरह से विकलांग नहीं हैं।

से संकेत (7) मैनुअल पृष्ठ :

वास्तविक समय के संकेतों को निम्नलिखित द्वारा प्रतिष्ठित किया जाता है:

  1. वास्तविक समय के संकेतों के कई उदाहरणों को पंक्तिबद्ध किया जा सकता है। इसके विपरीत, यदि मानक संकेत के कई उदाहरण वितरित किए जाते हैं, जबकि वह संकेत वर्तमान में अवरुद्ध है, तो केवल एक उदाहरण पंक्तिबद्ध है।

SIGRTMIN से SIGRTMAX तक की संख्या में सिग्नल का उपयोग करने का प्रयास करें।


वास्तविक समय के संकेतों के लिए एक सीमा है, लेकिन यह काफी अधिक है। यदि उपयोगकर्ता द्वारा भेजे गए बकाया लंबित संकेतों की संख्या RLIMIT_SIGPENDING से अधिक हो जाती है, तो एक संकेत छोड़ दिया जाएगा। ulimit -iयह मूल्य उबंटू 18.04 पर 63432 के रूप में दिखाता है।
बैन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.