2012-05-18 10 views
34

सबसे पहले, मुझे यह पूछना चाहिए कि कौन सा राज्य सबसे अच्छा है? उदाहरण के लिए एक वास्तविक समय MMORPG सर्वर। क्या होगा यदि मैं गैर-अवरुद्ध सॉकेट का उपयोग करने के बजाय प्रति क्लाइंट थ्रेड बनाता हूं? या क्या होगा यदि मैं एक थ्रेड का उपयोग करता हूं जिसमें सभी गैर-अवरुद्ध सॉकेट होते हैं? क्या आप मुझे फायदे बता सकते हैं?मुझे गैर-अवरुद्ध या अवरुद्ध सॉकेट का उपयोग क्यों करना चाहिए?

उत्तर

29

आपका प्रश्न एक बहुत लंबे समय तक चर्चा के लायक है, लेकिन यहाँ एक जवाब पर एक छोटा चाकू है:

  • अवरुद्ध सॉकेट का उपयोग कर मतलब यह है कि केवल एक ही सॉकेट क्योंकि यह ब्लॉक प्रतीक्षा करते हुए किसी भी एक सूत्र में किसी भी समय (कम से सक्रिय किया जा सकता है गतिविधि) के लिए
  • अवरुद्ध सॉकेट का उपयोग कर (अतुल्यकालिक प्रोग्रामिंग और अधिक जटिल हो जाता है)
  • आप सॉकेट प्रति 1 धागा बना सकते हैं आम तौर पर गैर-अवरुद्ध सॉकेट की तुलना में आसान है के रूप में आप ने कहा लेकिन धागे भूमि के ऊपर है और की तुलना में अत्यंत अक्षम हैं गैर-अवरुद्ध समाधान;
  • गैर अवरुद्ध सॉकेट साथ
  • आप ग्राहकों की एक बहुत बड़ी मात्रा संभाल सकता: यह एक एकल प्रक्रिया में लाखों के पैमाने सकता है - लेकिन कोड हो जाता है थोड़ा और अधिक जटिल

गैर अवरुद्ध सॉकेट के साथ (Windows पर) आप विकल्पों में से एक जोड़ी है:

  • मतदान
  • घटनाओं आधारित
  • मैं ओवरलैप/ओ

ओवरलैप I/O आपको सही ढंग से समझने और लागू करने के लिए सबसे जटिल मॉडल होने के खर्च पर सर्वश्रेष्ठ प्रदर्शन (हजारों सॉकेट/प्रक्रिया) प्रदान करेगा।

असल में यह प्रदर्शन बनाम प्रोग्रामिंग जटिलता के लिए नीचे आता है।

नोट

यहाँ क्यों एक धागा/सॉकेट मॉडल का उपयोग कर एक बुरा विचार है की एक बेहतर व्याख्या दी गई है:

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

+0

आप एक 80 रास्ता बॉक्स पर चल रहे हैं, तो आप कोई समस्या नहीं धागे के सैकड़ों बाहर चीर कर सकते हैं। –

+0

@ जॉन - सिर्फ इसलिए कि सैकड़ों धागे बनाना संभव है (यदि आपके पास पर्याप्त स्मृति है) तो इसका मतलब यह नहीं है कि यह एक अच्छा विचार है। वास्तव में यह एक बुरा विचार है! –

+9

मेरा बिंदु, स्वीकार्य रूप से अच्छी तरह से नहीं बनाया गया है, यह है कि आप केवल 20 पर मनमानी रेखा नहीं खींच सकते हैं और उस "बुरे" से परे किसी भी धागे को कॉल नहीं कर सकते हैं। –

8

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

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

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

  1. आप एक समय में कनेक्शन की एक छोटी संख्या के साथ काम कर रहे हैं
  2. आप आम तौर पर प्रत्येक कनेक्शन
  3. आप केवल काम कर रहे के लिए व्यापक संसाधन करना स्थानीय मेजबान के साथ ऐसा करने के लिए उन्हें अपने कनेक्शन तेजी से और भरोसेमंद है
  4. आप निष्पादन

से विकास अनुकूलित करने में अधिक चिंतित हैं,

1. ठीक है, तकनीकी रूप से केवल संभव तरीका नहीं है, लेकिन अधिकतर विकल्प अपेक्षाकृत बदसूरत हैं - अधिक विशिष्ट होने के लिए, मुझे लगता है कि जब आप यह समझने के लिए कोड जोड़ते हैं कि कोई समस्या है, और फिर समस्या को ठीक करें, यदि आपने केवल एक गैर-अवरुद्ध सॉकेट का उपयोग किया है, तो संभवतः आपने अधिक अतिरिक्त काम किया है।

+6

किसी अन्य थ्रेड संदर्भ से सॉकेट को डिस्कनेक्ट करके अवरुद्ध थ्रेड को समाप्त किए बिना अवरुद्ध सॉकेट ऑपरेशन को निरस्त करना संभव है। इससे अवरुद्ध ऑपरेशन त्रुटि कोड के साथ विफल हो जाएगा, फिर अवरुद्ध धागा सामान्य सफाई जैसे अन्य चीजों को आगे बढ़ा सकता है और कर सकता है। –

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