2012-10-07 16 views
5

मैं लिनक्स में एक सर्वर लिख रहा हूं जिसे एकाधिक ग्राहकों से एक साथ पढ़ने/लिखने के संचालन का समर्थन करना होगा। मैं पढ़ने/लिखने की उपलब्धता को प्रबंधित करने के लिए फ़ंक्शन का उपयोग करना चाहता हूं।"चयन" फ़ंक्शन के साथ गैर-अवरुद्ध सॉकेट का उपयोग करने का क्या फायदा है?

जो मुझे समझ में नहीं आता है यह है: मान लीजिए कि मैं सॉकेट के डेटा को पढ़ने के लिए उपलब्ध होने तक प्रतीक्षा करना चाहता हूं। के लिए प्रलेखन का चयन करता है कि यह तब तक ब्लॉक करता है जब तक डेटा पढ़ने के लिए उपलब्ध न हो, और पढ़ा गया कार्य ब्लॉक नहीं होगा।

तो यदि मैं चयन का उपयोग कर रहा हूं और मुझे पता है कि पढ़ा गया कार्य अवरुद्ध नहीं होगा, तो मुझे अपने सॉकेट को गैर-अवरुद्ध करने के लिए क्यों सेट करना होगा?

उत्तर

6

ऐसे मामले हो सकते हैं जब एक सॉकेट तैयार होने की सूचना दी जाती है लेकिन जब तक आप इसे जांचते हैं, तो यह इसके राज्य को बदल देता है।

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

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

2

लाभों में से एक यह है कि यह आपके द्वारा बनाई जाने वाली किसी भी प्रोग्रामिंग त्रुटियों को पकड़ लेगा, क्योंकि यदि आप एक सॉकेट को पढ़ने की कोशिश करते हैं जो आपको सामान्य रूप से अवरुद्ध करता है, तो आपको इसके बजाय EWOULDBLOCK मिल जाएगा। सॉकेट के अलावा अन्य वस्तुओं के लिए, सटीक एपीआई व्यवहार बदल सकता है, http://www.scottklement.com/rpg/socktut/nonblocking.html देखें।

+0

आह, इसके लिए धन्यवाद। :) – CaptainCodeman

1

यह स्नैकी ध्वनि के लिए जा रहा है लेकिन यह नहीं है। उन्हें गैर-अवरुद्ध करने का सबसे अच्छा कारण यह है कि आप ब्लॉक नहीं करते हैं।

इसके बारे में सोचें। select() आपको बताता है कि पढ़ने के लिए कुछ है लेकिन आप नहीं जानते कि कितना। 2 बाइट्स हो सकता है, 2,000 हो सकता है। ज्यादातर मामलों में select पर वापस जाने से पहले जो भी डेटा है, उसे निकालने के लिए और अधिक कुशलतापूर्ण है। तो आप

while (1) 
{ 
    n = read(sock, buffer, 200); 
    //check return code, etc 
} 

पढ़ने के लिए कुछ भी नहीं छोड़े जाने पर आखिरी पढ़ने पर क्या होता है? यदि सॉकेट गैर-अवरुद्ध नहीं है तो आप ब्लॉक करेंगे, जिससे select() के बिंदु को कम से कम आंशिक रूप से हराया जाएगा।

3

दूसरों द्वारा उल्लिखित कर्नेल बग के अलावा, गैर-अवरुद्ध सॉकेट चुनने का एक अलग कारण, यहां तक ​​कि एक मतदान लूप के साथ, यह है कि यह तेजी से आने वाले डेटा के साथ अधिक प्रदर्शन की अनुमति देता है। सोचें कि क्या होता है जब अवरुद्ध सॉकेट को "पठनीय" के रूप में चिह्नित किया जाता है। आपको पता नहीं है कि कितना डेटा आ गया है, ताकि आप इसे केवल एक बार सुरक्षित रूप से पढ़ सकें।फिर आपको अपने पाउडर को जांचने के लिए इवेंट लूप पर वापस जाना होगा कि सॉकेट अभी भी पठनीय है या नहीं। इसका मतलब यह है कि प्रत्येक एकल को सॉकेट से पढ़ने या लिखने के लिए आपको दो कम से कम दो सिस्टम कॉल करना पड़ता है: select आपको यह बताने के लिए सुरक्षित है कि पढ़ने के लिए सुरक्षित है, और पढ़ना/लिखना कॉल स्वयं ही है।

गैर-अवरुद्ध सॉकेट के साथ आप अनावश्यक कॉल को पहले के बाद select पर छोड़ सकते हैं। जब 0 सॉकेट को select द्वारा पठनीय के रूप में फ़्लैग किया जाता है, तो आपके पास डेटा लौटने तक इसे पढ़ने का विकल्प होता है, जो डेटा के त्वरित विस्फोटों की तेज़ी से प्रोसेसिंग की अनुमति देता है।

+0

धन्यवाद, बहुत अच्छा मुद्दा, मुझे नहीं पता था कि पढ़ने की कोशिश एक और चयन से तेज होगी। – CaptainCodeman