2010-07-29 15 views
9

कुछ दिन पहले मुझे एक ऐसी समस्या की जांच करनी पड़ी जहां मेरा आवेदन असामान्य रूप से उच्च CPU उपयोग दिखा रहा था जब यह स्पष्ट रूप से निष्क्रिय राज्य में था। मैंने समस्या को एक लूप पर ट्रैक किया जो recvfrom कॉल पर अवरुद्ध करने के लिए था, जबकि सॉकेट को O_NONBLOCK पर सेट किया गया था-जिसके परिणामस्वरूप स्पिन लॉक हो गया था। समस्या को हल करने के दो तरीके थे: poll या select का उपयोग करके सॉकेट पर उपलब्ध डेटा के लिए अवरुद्ध करने या मतदान करने के लिए सॉकेट सेट करें। मैंने पूर्व को चुना क्योंकि यह आसान था। लेकिन मैं सोच रहा हूं कि कोई भी गैर-अवरुद्ध सॉकेट क्यों बनायेगा और फिर अलग से मतदान करेगा। क्या अवरुद्ध सॉकेट एक जैसा नहीं करता है? उपयोग के मामले क्या हैं जहां कोई गैर-अवरुद्ध सॉकेट और मतदान संयोजन का उपयोग करेगा? क्या सामान्य मामलों में इसके लिए कोई फायदे हैं?मतदान के साथ गैर-अवरुद्ध सॉकेट

उत्तर

7

एक गैर अवरुद्ध फ़ाइल वर्णनकर्ता साथ poll() या select() का उपयोग करके आप दो लाभ होते हैं:

  • आप के लिए ब्लॉक करने के लिए एक समय समाप्ति सेट कर सकते हैं;
  • आप किसी भी फ़ाइल डिस्क्रिप्टर के सेट करने योग्य होने के लिए प्रतीक्षा कर सकते हैं।

यदि आपके पास प्रतीक्षा करने के लिए केवल एक फ़ाइल डिस्क्रिप्टर (सॉकेट) है, और आप इस पर अनिश्चित काल तक प्रतीक्षा नहीं करते हैं, तो हाँ; आप बस एक अवरुद्ध कॉल का उपयोग कर सकते हैं।

दूसरा लाभ वास्तव में select() और दोस्तों के लिए हत्यारा उपयोग केस है। इसका मतलब यह है कि आप एकाधिक सॉकेट कनेक्शन, साथ ही साथ मानक इनपुट और मानक आउटपुट और संभावित रूप से फ़ाइल I/O फ़ाइल को नियंत्रित कर सकते हैं, सभी नियंत्रण के एक थ्रेड के साथ।

1

जिसके परिणामस्वरूप स्पिन लॉक होता है।

उस स्थिति को सामान्यतः तंग लूप कहा जाता है।

समस्या को हल करने के दो तरीके थे: सॉकेट को मतदान या चयन का उपयोग करके सॉकेट पर उपलब्ध डेटा को अवरुद्ध करने या मतदान करने के लिए सेट करें। मैंने पूर्व को चुना क्योंकि यह आसान था।

आप यह सुनिश्चित करें कि अन्य कोड भागों को पहले से ही poll() (या select()) का उपयोग नहीं करते हैं और सॉकेट गैर अवरुद्ध मोड में होने की उम्मीद?

अन्यथा, फिर हाँ, ब्लॉकिंग मोड पर स्विच सबसे सरल समाधान है।

बेस्ट पार्श्व-संगत समाधान recvfrom() बुला poll() उपयोग करने के लिए सॉकेट के लिए प्रतीक्षा करने पठनीय बनने के लिए पहले हो गया होता। इस तरह से सुनिश्चित होता है कि कोड के अन्य भाग ठीक पहले कार्य करेंगे।

लेकिन मुझे आश्चर्य है कि कोई भी गैर-अवरुद्ध सॉकेट क्यों बनायेगा और फिर इसे अलग से मतदान करेगा। क्या अवरुद्ध सॉकेट एक जैसा नहीं करता है?

recvfrom() के मामले में मेरे लिए कोई बड़ा अंतर ज्ञात नहीं है।

उपयोग के मामले क्या हैं जहां कोई गैर-अवरुद्ध सॉकेट और मतदान संयोजन का उपयोग करेगा? क्या सामान्य मामलों में इसके लिए कोई फायदे हैं?

एक सरल कोडिंग गलती हो सकती है। या किसी ने सोचा होगा कि तंग लूप में रिकॉइंग किसी भी तरह प्रदर्शन को बढ़ाएगा।

0

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

1

मैं यहां पोस्ट कर रहा हूं, क्योंकि सवाल पुराना है। यह किसी भी तरह से मेरी Google खोज में आया और निश्चित रूप से ठीक से जवाब नहीं दिया गया है।

स्वीकृत उत्तर केवल गैर-अवरुद्ध सॉकेट का उपयोग करने के दो फायदों को हाइलाइट करता है लेकिन वास्तव में विस्तार से नहीं जाता है या वास्तविक प्रश्न का उत्तर नहीं देता है।

  • नोट: दुर्भाग्य से सबसे ऑनलाइन गैर अवरुद्ध सॉकेट पर "ट्यूटोरियल" या कोड के टुकड़े केवल सॉकेट कोड अवरोधित करने की सुविधा है, तो ज्ञान कम प्रसार है।

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

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

अब गैर-अवरुद्ध सॉकेट का उपयोग करके, आप गेमरवर को सिंगल-थ्रेड पर चला सकते हैं, गैमेस्टेट के साथ-साथ सॉकेट को अपडेट कर सकते हैं ... चलो 50 एमएमएस टाइमआउट अंतराल - और सॉकेट डेटा केवल पढ़ा जाता है कनेक्टेड उपयोगकर्ताओं से जब वे वास्तव में कुछ भेजते हैं, और उसके बाद सर्वर सिमुलेशन में खिलाया जाता है, संसाधित और अगले टिक के लिए गेम स्टेट गणना में खिलाया जाता है।

+0

'चयन करें' और 'मतदान' ब्लॉकिंग समस्या को कम नहीं करते हैं, यह सूचित करते हुए कि एक विशेष ऑपरेशन ** जब आप उस ऑपरेशन को करने के लिए जाते हैं तो ** ब्लॉक नहीं करेगा? क्या इन अच्छे उत्पादन अनुप्रयोगों को अभी भी अवरुद्ध करना अक्षम है? – TheBuzzSaw

+0

@TheBuzzSaw मुझे यकीन नहीं है कि मैं सवाल समझता हूं। हम यहां एकल सॉकेट उपयोग को छोड़ रहे हैं, इसलिए आपके पास फ़ाइल डिस्क्रिप्टर का एक सेट है जिसे आप प्रति कॉल का उपयोग करते हैं, और यह चयन नहीं है, लेकिन वास्तविक रिकॉव कॉल जो ब्लॉक करता है, डेटा प्राप्त करने की प्रतीक्षा करता है। –

+0

मैं कह रहा हूं कि जब कोई प्रोग्राम दर्जन से अधिक सॉकेट्स को मल्टीप्लेक्स करने के लिए 'चयन' का उपयोग करता है, तो आमतौर पर उन सॉकेट को गैर-अवरुद्ध मोड में डालने में कोई बात नहीं होती है क्योंकि' चयन 'करने के लिए कॉल निर्धारित करता है कि कौन से क्रियाएं अवरुद्ध नहीं होंगी। यदि 'चयन करें' रिटर्न और मुझे बताएं कि सॉकेट '45' एक पठन पर अवरुद्ध नहीं होगा, तो मैं ब्लॉक के डर के बिना 'आरईआरवी' कह सकता हूं, है ना? – TheBuzzSaw

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