2009-02-12 10 views
24

select(2) समारोह के व्यवहार जब किसी फ़ाइल वर्णनकर्ता यह पढ़ने के लिए देख रहा है एक और धागा द्वारा बंद कर दिया गया है क्या है?क्या करता है का चयन करें (2) आप एक अलग थ्रेड में (2) एक फ़ाइल वर्णनकर्ता बंद कर देते हैं?

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

+0

[सॉकेट चयन से बाहर तोड़ने का संभावित डुप्लिकेट] (http://stackoverflow.com/questions/2486727/breaking-out-from-socket-select) – iammilind

+0

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

+0

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

उत्तर

21

कुछ अतिरिक्त जांच से, ऐसा लगता है कि दोनों DWC और bothie ठीक कह रहे हैं।

bothie's answer प्रश्न के लिए उबलता है: यह अपरिभाषित व्यवहार है।इसका मतलब यह नहीं है कि यह अनिवार्य रूप से अप्रत्याशित है, लेकिन अलग-अलग ओएस इसे अलग-अलग करते हैं। ऐसा लगता है कि सोलारिस और इस मामले में select(2) से HP-UX वापसी, लेकिन लिनक्स सिस्टम की तरह लिनक्स कर्नेल मेलिंग सूची पर तर्क अनिवार्य है कि यह अपरिभाषित है से 2001

this post to the linux-kernel mailing list के आधार पर नहीं करता है (और टूट) पर भरोसा करने के लिए व्यवहार। लिनक्स के मामले में, फाइल डिस्क्रिप्टर पर close(2) पर कॉल करने से प्रभावी रूप से संदर्भ संदर्भ कम हो जाता है। चूंकि select(2) कॉल इसके संदर्भ में भी है, इसलिए एफडी खुला रहेगा और select(2) रिटर्न तक इनपुट के लिए प्रतीक्षा कर रहा है। यह मूल रूप से dwc's answer है। आपको फ़ाइल डिस्क्रिप्टर पर एक ईवेंट मिलेगा और फिर इसे बंद कर दिया जाएगा। इससे पढ़ने की कोशिश करने से ईबीएडीएफ का परिणाम होगा, यह मानते हुए कि एफडी का पुनर्नवीनीकरण नहीं किया गया है। (एक चिंता है कि मार्कआर ने his answer में बनाया है, हालांकि मुझे लगता है कि यह उचित सिंक्रनाइज़ेशन के साथ ज्यादातर मामलों में शायद टालने योग्य है।)

तो मदद के लिए सभी को धन्यवाद।

+0

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

6

मुझे उम्मीद है कि यह व्यवहार करेगा जैसे कि फ़ाइल का अंत तक पहुंच गया था, ऐसा कहने के लिए, यह फ़ाइल डिस्क्रिप्टर के रूप में दिखाया जाएगा, लेकिन बाद में इसे पढ़ने का कोई भी प्रयास "खराब फ़ाइल डिस्क्रिप्टर" "।

कहा करने के बाद कि, कि कर बहुत बुरा व्यवहार वैसे भी है, जैसा कि आप हमेशा संभावित दौड़ की स्थिति के रूप में एक ही नंबर के साथ एक और फ़ाइल वर्णनकर्ता अभी तक एक और धागा के तुरंत बाद अन्य 2 इसे बंद कर दिया द्वारा खोला जा सकता है होगा, तो चयन धागा गलत पर इंतजार कर समाप्त हो जाएगा।

जैसे ही आप एक फ़ाइल को बंद के रूप में, अपने नंबर पुनः उपयोग के लिए उपलब्ध हो जाता है, और खोलने के लिए अगले कॉल द्वारा पुन: उपयोग किया जा सकता है(), सॉकेट() आदि, यहां तक ​​कि एक और धागा द्वारा यदि। इसलिए आप वास्तव में, वास्तव में इस तरह की चीज़ से बचने की जरूरत है।

+0

मैंने सोचा कि यह भी तैयार हो सकता है, लेकिन यह बिल्कुल सही नहीं है: वर्णनकर्ता वास्तव में तैयार राज्य में नहीं है - यह बंद है। और जैसा कि आप उल्लेख करते हैं, जब तक आप इसे इस्तेमाल करने के लिए जाते हैं, इसे किसी और चीज़ के लिए फिर से सौंप दिया जा सकता है। –

+0

हालांकि, एफडी युक्त डेटा संरचना के लिए आप mutex का उपयोग करके दौड़ से बच सकते हैं। लेकिन यह केवल तभी काम करेगा जब चयन() कॉल में टाइमआउट परिभाषित किया गया हो। –

2

यह थोड़ा भ्रमित है कि तुम क्या कह रहे हैं ...

चुनें() एक "दिलचस्प" परिवर्तन पर लौट जाना है। अगर क्लोज़() ने केवल संदर्भ गणना में कमी की है और फाइल कहीं भी लिखने के लिए खुली थी तो उठने के लिए चयन() के लिए कोई कारण नहीं है।

तो अन्य धागा पास किया था() ही खुला वर्णनकर्ता पर तो यह और अधिक दिलचस्प हो जाता है, लेकिन मैं कोड का एक सरल संस्करण देखने के लिए अगर कुछ वास्तव में गलत है देखने की जरूरत होगी।

5

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

यह अतिरिक्त का मतलब है, अलग धागे के लिए कोई जरूरत नहीं है, क्योंकि सभी काम करते हैं, कि धागे में किया जा सकता है और साथ ही चुनिंदा कॉल करने से पहले किया जा सकता है। और काम समय लगता है, की तुलना में यह बाधित किया जा सकता है, समय समाप्त = {0,0} के साथ बुलाया जा रहा है चुनें, फ़ाइल वर्णनकर्ता संभाला हो और बाद में काम फिर से शुरू किया जा रहा है।

अब, आप एक और धागा में एक फ़ाइल वर्णनकर्ता बंद कर दें। आपके पास वह अतिरिक्त धागा क्यों है, और यह फाइल डिस्क्रिप्टर को क्यों बंद कर देगा?

पीओएसईक्स मानक कोई संकेत नहीं देता है, इस मामले में क्या होता है, तो आप जो कर रहे हैं वह अविश्वसनीय बहेवियर है। उम्मीद है कि परिणाम विभिन्न ऑपरेटिंग सिस्टम और एक ही ओएस के संस्करण के बीच भी बहुत अलग होगा।

सादर, बोडो

+1

मुझे लगता है कि यह वैसे भी अपरिभाषित व्यवहार होगा, क्योंकि फ़ाइल डिस्क्रिप्टर की दौड़ की स्थिति को बंद करना असंभव है * चयन से पहले और दूसरा नंबर एक ही नंबर के साथ खोला जा रहा है। – MarkR

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