2012-12-03 10 views
18

जो मैं समझता हूं उससे, आप अपना लिनक्स डेमॉन लिखते हैं जो एक अंतहीन पाश में अनुरोध को सुनता है।
कुछ की तरह ..अंतहीन है जबकि लूप CPU संसाधनों को लेता है?

int main() { 
    while(1) { 
     //do something... 
    } 
} 

रेफरी: http://www.thegeekstuff.com/2012/02/c-daemon-process/

मैंने पढ़ा एक कार्यक्रम सो करता है कि यह इंतजार कर मोड में जाने तो यह संसाधनों खा नहीं है।

1. अगर मैं चाहता हूं कि मेरा डिमन प्रत्येक 1 सेकंड के लिए अनुरोध की जांच करे, तो निम्नलिखित संसाधन उपभोग करेंगे?

int main() { 
    while(1) { 
     if (request) { 
      //do something... 
     } 
     sleep(1) 
    } 
} 

2. अगर मैं नींद को हटाना चाहता था, तो क्या इसका मतलब है कि सीपीयू खपत 100% बढ़ जाएगी?

3. क्या संसाधनों को खाने के बिना अंतहीन पाश चलाने के लिए संभव है? कहो .. अगर यह कुछ भी नहीं करता है लेकिन सिर्फ खुद को लूप्स करता है। या बस सो जाओ (1)।

अंतहीन लूप और सीपीयू संसाधन मेरे लिए एक रहस्य है।

+1

स्लीपिंग शेड्यूलर को आपकी प्रक्रिया के बजाय सीपीयू पर कुछ अन्य प्रक्रिया चलाने के लिए शेड्यूलर बताती है (यह भी सरल रखें)। सोते समय आपका प्रोग्राम किसी भी CPU संसाधन का उपभोग नहीं करेगा। यहां तक ​​कि कुछ मिलीसेकंड के लिए भी सोते हुए चीजें एक अंतहीन पाश में चिकनी बनाती हैं जैसे आपने इसे दिखाया है। –

+3

यदि आप * सुन रहे हैं * तो आपको कुछ मल्टीप्लेक्सिंग सिस्कल जैसे 'पोल (2) '(या पुराने, लगभग अप्रचलित,' चयन (2)') –

उत्तर

12

क्या संसाधनों को खाने के बिना अंतहीन पाश चलाने के लिए संभव है? कहो .. अगर यह कुछ भी नहीं करता है लेकिन सिर्फ खुद को लूप्स करता है। या बस सो जाओ (1)।

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

+1

"कोई संसाधन नहीं खाएगा" बिल्कुल सही नहीं है। एक सेमफोर बनाना कर्नेल संसाधनों और वस्तुओं का उपयोग करता है और यह काफी भारी ऑपरेशन है। सेमफोर पर प्रतीक्षा करना एक कर्नेल-मोड ऑपरेशन है और कर्नेल मोड में एक संदर्भ स्विच भी होगा। –

+0

टाइमआउट का उपयोग होने पर एक सेमफोर उपयुक्त होगा, लेकिन नींद अभी भी सबसे अच्छी है। यदि आप अपना कोड * या * टाइमआउट * या * कुछ बाहरी ईवेंट पर ट्रिगर करना चाहते हैं तो सेमफोर सबसे प्रासंगिक है। –

+0

सेमफोर का जिक्र करने के लिए धन्यवाद। पता होना चाहिए कि समय आने पर :) – resting

2

संक्षिप्त उत्तर हाँ है - नींद को हटाने से 100% सीपीयू मिलता है - लेकिन उत्तर कुछ अतिरिक्त विवरणों पर निर्भर करता है। यह सभी सीपीयू का उपभोग करता है, जब तक ...

  1. लूप बॉडी छोटा है, और अनुकूलित किया गया है।
  2. लूप में एक अवरुद्ध ऑपरेशन होता है (जैसे फ़ाइल या नेटवर्क ऑपरेशन)। आपके द्वारा प्रदान किया गया लिंक इस से बचने के लिए सुझाव देता है, लेकिन जब तक कुछ प्रासंगिक होता है तब तक ब्लॉक करना अक्सर अच्छा विचार होता है।

संपादित करें: आपके परिदृश्य के लिए, मैं @ एएलएस द्वारा किए गए सुझाव का समर्थन करता हूं।

संपादित करें 2: मुझे उम्मीद है कि इस उत्तर को -1 प्राप्त हुआ है क्योंकि मेरा दावा है कि ब्लॉकिंग ऑपरेशन वास्तव में एक अच्छा विचार हो सकता है। [यदि आप -1, आपको एक टिप्पणी में प्रेरणा छोड़नी चाहिए ताकि हम सभी कुछ सीख सकें।]

वर्तमान लोकप्रिय सोच यह है कि गैर-ब्लॉक (घटना-आधारित) आईओ अच्छा है और अवरोध खराब है। यह दृश्य oversimplified है क्योंकि यह सभी सॉफ़्टवेयर मानता है जो आईओ निष्पादित करता है गैर-अवरुद्ध संचालन का उपयोग करके थ्रूपुट को बेहतर बना सकता है।

क्या? क्या मैं वास्तव में सुझाव दे रहा हूं कि गैर-अवरुद्ध आईओ का उपयोग करके वास्तव में थ्रूपुट कम हो सकता है? हाँ यह कर सकते हैं। जब कोई प्रक्रिया एक ही गतिविधि की सेवा करती है तो वास्तव में आईओ को अवरुद्ध करने के लिए बेहतर होता है क्योंकि आईओ को अवरुद्ध करने से केवल उन संसाधनों को जला दिया जाता है जिन्हें पहले से ही प्रक्रिया के अस्तित्व में भुगतान किया जा चुका है।

इसके विपरीत, गैर अवरुद्ध आईओ सरल अवरुद्ध आईओ की तुलना में अधिक निश्चित भूमि के ऊपर ले जा सकता है। यदि प्रक्रिया अतिरिक्त आईओ आपूर्ति करने में सक्षम नहीं है जिसे इंटरलीव किया जा सकता है, तो गैर-अवरुद्ध सेटअप के लिए भुगतान करके कुछ भी प्राप्त नहीं हुआ है। (व्यावहारिक रूप से, अनुचित गैर-अवरुद्ध आईओ की सबसे बड़ी लागत केवल अतिरिक्त कोड जटिलता में है। इसके अलावा, यह विषय काफी हद तक एक विचार अभ्यास है।)

आईओ अवरुद्ध करने के तहत हम उन प्रक्रियाओं को निर्धारित करने के लिए ऑपरेटिंग सिस्टम पर भरोसा करते हैं जो प्रगति कर सकता है। ओएस को ऐसा करने के लिए डिज़ाइन किया गया है।

के तहत गैर-अवरुद्ध आईओ हम अधिक से अधिक सेटअप लागत है लेकिन इस प्रक्रिया के संसाधनों और interleaved काम के बीच अपने धागे साझा कर सकते हैं

। गैर-अवरुद्ध आईओ किसी भी प्रक्रिया के लिए आदर्श है जो कई स्वतंत्र गतिविधियों, जैसे वेब सर्वर परोसता है। गैर-अवरुद्ध आईओ के निश्चित लागत ओवरहेड से प्राप्त थ्रूपुट काफी बेहतर है।

+0

सॉफ़्टवेयर गैर-अवरुद्ध I/O का उपयोग करके थ्रूपुट में सुधार नहीं कर सकता है, लेकिन यह हमेशा * प्रतिक्रिया * में सुधार करता है। हां, आपको अवरुद्ध करना चाहिए, लेकिन यह एक अवरुद्ध कॉल होना चाहिए जो कई प्रकार की घटनाओं की प्रतीक्षा करता है, न कि अवरुद्ध I/O कॉल जो उपयोगकर्ता इनपुट को अनदेखा कर देता है जब तक I/O पूरा नहीं हो जाता। 'चयन करें', 'मतदान', 'aio_suspend' सभी उदाहरण हैं। आप कहते हैं, "यदि प्रक्रिया अतिरिक्त आईओ आपूर्ति करने में सक्षम नहीं है जिसे इंटरलीव किया जा सकता है", लेकिन ऐसा होने से कम से कम एक अतिरिक्त इनपुट होता है ... उपयोगकर्ता छोड़ने का अनुरोध करता है। –

+0

@BenVoigt यह सच है। इंटरैक्टिव एप्लिकेशन अनिश्चित काल तक अवरुद्ध नहीं होना चाहिए, उदा। एक सेमफोर फिर एक टाइमआउट का उपयोग करना चाहिए। उस ने कहा, पॉलीक्स बैकएंड सेवाएं अवरुद्ध करने के दौरान भी संकेत प्राप्त कर सकती हैं। सब कुछ, आपने याद रखने के लिए एक अच्छा मुद्दा उठाया है - धन्यवाद। –

13

poll और select कॉल (एक टिप्पणी में बेसिल स्टैरेनकेविच द्वारा उल्लिखित) या एक सेमफोर (उत्तर में एलएस द्वारा उल्लिखित) परिस्थितियों के आधार पर अनुरोधों की प्रतीक्षा करने के सही तरीके हैं। poll या select के बिना ऑपरेटिंग सिस्टम पर, कुछ समान होना चाहिए।

न तो sleep, YieldProcessor, न ही sched_yield निम्नलिखित कारणों से ऐसा करने के उचित तरीके हैं।

YieldProcessor और sched_yield केवल प्रक्रिया को चलने योग्य कतार के अंत तक ले जाएं लेकिन इसे चलाने योग्य छोड़ दें। प्रभाव यह है कि वे अन्य प्रक्रियाओं को निष्पादित करने के लिए समान या उच्च प्राथमिकता पर अनुमति देते हैं, लेकिन, जब उन प्रक्रियाओं को पूरा किया जाता है (या यदि कोई नहीं है), तो YieldProcessor या sched_yield नामक प्रक्रिया चलती रहती है। यह दो समस्याओं का कारण बनता है। एक यह है कि कम प्राथमिकता प्रक्रिया अभी भी नहीं चलेगी। दूसरा यह है कि यह प्रोसेसर को ऊर्जा का उपयोग करके हमेशा चल रहा है। हम ऑपरेटिंग सिस्टम को पहचानने के लिए पसंद करेंगे जब किसी प्रक्रिया को चलाने की आवश्यकता नहीं होती है और प्रोसेसर को कम-शक्ति स्थिति में डाल दिया जाता है।

sleep इस निम्न-शक्ति स्थिति की अनुमति दे सकता है, लेकिन यह अनुमान लगाने वाला गेम खेलता है कि अगला अनुरोध आने तक कितना समय लगेगा, जब आवश्यकता नहीं होती है तो प्रोसेसर बार-बार जागता है, और यह प्रक्रिया को कम प्रतिक्रियाशील बनाता है अनुरोध करने के लिए, क्योंकि अनुरोधित समय की समाप्ति तक प्रक्रिया जारी रहेगी, भले ही सेवा करने का अनुरोध हो।

poll और select कॉल बिल्कुल इस स्थिति के लिए डिज़ाइन किए गए हैं। वे ऑपरेटिंग सिस्टम को बताते हैं कि यह प्रक्रिया अपने आई/ओ चैनलों में से किसी एक पर आने वाले अनुरोध की सेवा करना चाहती है लेकिन अन्यथा ऐसा करने का कोई काम नहीं है। यह ऑपरेटिंग सिस्टम को प्रक्रिया को चिह्नित करने की अनुमति देता है और उपयुक्त होने पर प्रोसेसर को कम-शक्ति स्थिति में रखने की अनुमति देता है।

एक सेमाफोर का प्रयोग छोड़कर संकेत प्रक्रिया को जगाने के लिए एक आई/ओ चैनल में उत्पन्न होने वाली गतिविधि के बजाय सेमाफोर को ऊपर उठाने के किसी अन्य प्रक्रिया से आता है कि, एक ही व्यवहार करती है। Semaphores उपयुक्त हैं जब कुछ काम करने के संकेत इस तरह से आता है; बस poll का उपयोग करें या एक सेमफोर आपकी स्थिति के लिए अधिक उपयुक्त है।

आलोचना poll, select, या एक सेमफोर का कारण कर्नेल-मोड कॉल अप्रासंगिक है, क्योंकि अन्य विधियां कर्नेल-मोड कॉल भी करती हैं। एक प्रक्रिया अपने आप नहीं सो सकती है; इसे ऑपरेटिंग सिस्टम को अनुरोध करने के लिए इसे कॉल करना होगा। इसी प्रकार, YieldProcessor और sched_yield ऑपरेटिंग सिस्टम के लिए अनुरोध करते हैं।

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