2010-10-21 19 views
13

मैं कुछ कोड लिख रहा हूं जो कुछ मौजूदा को प्रतिस्थापित करता है:जीसीडी डिस्पैच स्रोतों और चयन() के बीच क्या अंतर है?

while(runEventLoop){ 
    if(select(openSockets, readFDS, writeFDS, errFDS, timeout) > 0){ 
    // check file descriptors for activity and dispatch events based on same 
    } 
} 

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

हालांकि, जब मैंने इसे एक ऐसे रूप में दोबारा करने की कोशिश की जो प्रेषण स्रोतों पर निर्भर करता है जो सॉकेट डिस्क्रिप्टर पर DISPATCH_SOURCE_TYPE_READ और DISPATCH_SOURCE_TYPE_WRITE से जुड़े ईवेंट हैंडलर से निकाला गया है, लाइब्रेरी कोड इस शेड्यूलिंग पर निर्भर काम करना बंद कर दिया। मेरी पहली धारणा यह है कि मैं DISPATCH_SOURCE_TYPE_READ और DISPATCH_SOURCE_TYPE_WRITE के उपयोग को गलत समझा रहा हूं - मैंने माना था कि वे उन सॉकेट डिस्क्रिप्टरों के साथ चयन() को कॉल करने के समान मोटे तौर पर वही व्यवहार करेंगे।

क्या मैं जीसीडी प्रेषण स्रोतों को गलत समझता हूं? या, रिफैक्टर के संबंध में, क्या मैं इसे ऐसी परिस्थिति में उपयोग कर रहा हूं जहां यह सबसे उपयुक्त नहीं है?

+0

आपको अपना कोड दिखाना चाहिए - आपने जो कोशिश की थी। इस बीच, माइक एश के पास कुछ नमूना कोड है - http://www.mikeash.com/svn/GCDWeb/GCDWeb.m - जीसीडी वेब सर्वर। – robertvojta

उत्तर

3

आपके प्रश्न का संक्षिप्त उत्तर यह है: कोई भी नहीं। कोई अंतर नहीं है, जीसीडी प्रेषण स्रोत और select() दोनों एक ही काम करते हैं: वे उपयोगकर्ता को सूचित करते हैं कि एक विशिष्ट कर्नेल घटना हुई या कोई विशेष स्थिति सत्य है।

ध्यान दें कि, पर एक मैक या iOS डिवाइस आप select() उपयोग नहीं करना चाहिए, बल्कि और अधिक उन्नत kqueue() और kevent() (या kevent64())।

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

मूल कोड को बनाए रखने के लिए एक आसान समाधान हो सकता है, जो घटनाओं पर प्रतिक्रिया करने वाले भाग में जीसीडी कोड जोड़ रहा है। यहां, आप विशेष प्रकार की घटना के आधार पर अलग-अलग कतारों पर ईवेंट भेजते हैं।

+0

मैं मानता हूं, एक अंतर यह है कि जीसीडी के साथ आप प्रत्येक कोड से जुड़े स्वतंत्र प्रेषण कतारों के साथ अलग-अलग राज्य मशीनों में अपने कोड को मॉड्यूलर कर सकते हैं। मुझे यकीन नहीं है लेकिन मुझे लगता है कि आंतरिक रूप से जीसीडी कुछ चुनने के समान ही इस्तेमाल कर सकता है। – user210504

+2

क्या आप आईओएस पर चयन() से kqueue() बेहतर क्यों हैं, इस बारे में अधिक विशिष्ट हो सकते हैं? मेरी संक्षिप्त खोज से, ऐसा लगता है कि जब आपके पास निगरानी करने के लिए कई घटनाएं होती हैं तो kqueue() को प्राथमिकता दी जाती है, लेकिन क्या यह मानने का कोई कारण है कि यह fdset पर एकल fd के साथ चयन() से बेहतर है? उस स्थिति में, ऐसा लगता है कि अर्थशास्त्र लगभग समान हैं, इसलिए सुनिश्चित नहीं है कि प्रदर्शन अलग क्यों होगा? – user1055568

+1

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

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