जवाबों:
मुझे लगता है कि यह आपके प्रश्न का उत्तर देता है:
रिचर्ड स्टीवंस (rstevens@noao.edu) से:
मूल अंतर यह है कि चयन () का fd_set थोड़ा मुखौटा है और इसलिए इसका कुछ निश्चित आकार है। कर्नेल के लिए इस आकार को सीमित नहीं करना संभव होगा, जब कर्नेल संकलित किया जाता है, तो एप्लिकेशन को FD_SETSIZE को जो कुछ भी चाहिए उसे परिभाषित करने की अनुमति मिलती है (जैसा कि सिस्टम हेडर में टिप्पणियों का अर्थ है आज), लेकिन यह अधिक काम लेता है। 4.4BSD के कर्नेल और सोलारिस लाइब्रेरी फ़ंक्शन दोनों की यह सीमा है। लेकिन मैं देखता हूं कि बीएसडी / ओएस 2.1 को अब इस सीमा से बचने के लिए कोडित किया गया है, इसलिए यह उल्लेखनीय है, बस प्रोग्रामिंग का एक छोटा सा मामला है। :-) किसी को इस पर सोलारिस बग रिपोर्ट दर्ज करनी चाहिए, और देखें कि क्या यह कभी भी ठीक हो जाता है।
पोल () के साथ, हालांकि, उपयोगकर्ता को पोलफेड संरचनाओं की एक सरणी आवंटित करनी चाहिए, और इस सरणी में प्रविष्टियों की संख्या को पास करना होगा, इसलिए कोई मौलिक सीमा नहीं है। जैसा कि कैस्पर नोट करता है, चुनिंदा की तुलना में कम सिस्टम में पोल () होता है, इसलिए बाद वाला अधिक पोर्टेबल होता है। इसके अलावा, मूल कार्यान्वयन (SVR3) के साथ आप डिस्क्रिप्टर को -1 में सेट नहीं कर सकते हैं ताकि कर्नेल को पोलफेड संरचना में एक प्रविष्टि को अनदेखा कर सकें, जिससे सरणी से प्रविष्टियों को निकालना मुश्किल हो गया; SVR4 इसी के आसपास मिलता है। व्यक्तिगत रूप से, मैं हमेशा चुनिंदा () और शायद ही कभी पोल () का उपयोग करता हूं, क्योंकि मैं अपने कोड को बीएसडी वातावरण में भी पोर्ट करता हूं। इन वातावरणों के लिए कोई व्यक्ति चुनाव () का उपयोग करने वाला चयन () का उपयोग कर सकता है, लेकिन मैंने कभी नहीं देखा है। POSIX 1003.1g द्वारा दोनों चयन () और पोल () का मानकीकरण किया जा रहा है।
ऊपर उल्लिखित ईमेल कम से कम 2001 जितना पुराना है; poll()
बीएसडी सहित - आदेश अब (2017) सभी आधुनिक ऑपरेटिंग सिस्टम पर समर्थित है। वास्तव में, कुछ लोगों का मानना है कि select()
पदावनत होना चाहिए । एक तरफ राय, पोर्टेबिलिटी के मुद्दे poll()
अब आधुनिक प्रणालियों पर चिंता का विषय नहीं हैं। इसके अलावा, epoll()
तब से विकसित किया गया है (आप मैन पेज पढ़ सकते हैं ), और लोकप्रियता में वृद्धि जारी है।
आधुनिक विकास के लिए आप शायद इसका उपयोग नहीं करना चाहते हैं select()
, हालांकि इसमें स्पष्ट रूप से कुछ भी गलत नहीं है। poll()
, और यह और अधिक आधुनिक विकास है epoll()
, उसी तरह की सुविधाएँ (और अधिक) प्रदान करते हैं जैसे select()
कि सीमाओं से पीड़ित हैं।
select
या poll
:(
select()
कॉल आप जो सॉकेट और फ़ाइल वर्णनकर्ता आप पढ़ने के लिए देखने के लिए, लेखन चाहते हैं निशान के तीन bitmasks, और त्रुटियों, और फिर ऑपरेटिंग सिस्टम के निशान जो वास्तव में लोगों गतिविधि के कुछ प्रकार पड़ा है बनाने है; poll()
क्या आपने डिस्क्रिप्टर आईडी की एक सूची बनाई है, और ऑपरेटिंग सिस्टम उनमें से प्रत्येक को उस तरह की घटना के साथ चिह्नित करता है जो घटित हुई थी।
select()
विधि बल्कि भद्दा और अक्षम है।
आमतौर पर एक प्रक्रिया के लिए एक हजार से अधिक संभावित फ़ाइल विवरण उपलब्ध होते हैं। यदि लंबे समय से चल रही प्रक्रिया में केवल कुछ ही डिस्क्रिप्टर हैं, लेकिन उनमें से कम से कम एक को एक उच्च संख्या सौंपी गई है, तो select()
उस उच्चतम डिस्क्रिप्टर को समायोजित करने के लिए बिटमास्क काफी बड़ा होना चाहिए - इसलिए सैकड़ों बिट्स की पूरी रेंज इस बात से बेफिक्र रहें कि ऑपरेटिंग सिस्टम को हर select()
कॉल पर यह पता लगाना है कि वे परेशान हैं।
एक बार select()
रिटर्न, कॉल करने वाले को यह निर्धारित करने के लिए कि सभी घटनाओं को अंजाम देने के लिए सभी तीन बिटकॉम्स पर लूप करना होगा। बहुत से विशिष्ट अनुप्रयोगों में केवल एक या दो फ़ाइल डिस्क्रिप्टर को किसी भी समय नया ट्रैफ़िक मिलेगा, फिर भी सभी तीन बिटमास्क को अंत तक सभी तरह से पढ़ा जाना चाहिए कि वे कौन से डिस्क्रिप्टर हैं।
क्योंकि ऑपरेटिंग सिस्टम बिटकॉइन को फिर से लिखकर आपको गतिविधि के बारे में संकेत देता है, वे बर्बाद हो गए हैं और अब उन फ़ाइल विवरणकर्ताओं की सूची के साथ चिह्नित नहीं हैं जिन्हें आप सुनना चाहते हैं। आपको या तो पूरे बिटमास्क को किसी अन्य सूची से पुनर्निर्माण करना होगा जिसे आप मेमोरी में रखते हैं, या आपको memcpy()
प्रत्येक select()
कॉल के बाद बर्बाद किए गए बिटकॉम्स के ऊपर प्रत्येक बिटमास्क और डेटा के ब्लॉक की एक डुप्लिकेट कॉपी रखनी होगी ।
इसलिए poll()
दृष्टिकोण बहुत बेहतर काम करता है क्योंकि आप समान डेटा संरचना का फिर से उपयोग कर सकते हैं।
वास्तव में, poll()
आधुनिक लिनक्स कर्नेल में अभी तक एक और तंत्र को प्रेरित किया है: epoll()
जो कि स्केलेबिलिटी में एक और छलांग की अनुमति देने के लिए तंत्र पर और भी अधिक सुधार करता है, क्योंकि आज के सर्वर अक्सर एक साथ हजारों कनेक्शनों को संभालना चाहते हैं। यह प्रयास का एक अच्छा परिचय है:
http://scotdoyle.com/python-epoll-howto.html
जबकि इस लिंक के कुछ अच्छे रेखांकन हैं, जिनमें से लाभ दिखाते हैं epoll()
(आप ध्यान देंगे कि select()
इस बिंदु को इतना अक्षम और पुराने जमाने का माना जाता है कि इन ग्राफों पर एक लाइन भी नहीं मिलती है!)।
http://lse.sourceforge.net/epoll/index.html
अद्यतन: यहाँ एक और ढेर अतिप्रवाह प्रश्न है, जिसका उत्तर मतभेदों के बारे में और भी अधिक विवरण देता है:
दोनों ही धीमे और ज्यादातर समान हैं , लेकिन आकार में भिन्न हैं और कुछ प्रकार की विशेषताएं हैं!
जब आप एक पुनरावृत्ति लिखते हैं, तो आपको select
हर बार सेट की प्रतिलिपि बनाने की आवश्यकता होती है ! जबकि poll
सुंदर कोड रखने के लिए इस तरह की समस्या को ठीक किया है। एक और अंतर यह है कि poll
डिफ़ॉल्ट रूप से 1024 से अधिक फ़ाइल डिस्क्रिप्टर (एफडी) संभाल सकते हैं। poll
इस तरह की नौकरी को संभालने के लिए बहुत सारे चर होने के बजाय कार्यक्रम को अधिक पठनीय बनाने के लिए विभिन्न घटनाओं को संभाल सकते हैं। बहुत सारे चेक होने के कारण परिचालन poll
और select
रैखिक और धीमा है।