2009-03-18 10 views
10

से एक ही अवरुद्ध सॉकेट पर कॉल आरईवी() क्या होता है यदि मेरे पास एक सॉकेट, s है, तो वर्तमान में कोई डेटा उपलब्ध नहीं है, यह एक अवरुद्ध सॉकेट है, और मैं इसे recv पर दो धागे से कॉल करता हूं एक बार? क्या धागे में से एक डेटा प्राप्त करेगा? क्या दोनों इसे प्राप्त करेंगे? क्या दूसरी कॉल recv त्रुटि के साथ वापस आएगी?दो थ्रेड

उत्तर

10

एक धागा इसे प्राप्त करेगा, और यह बताने का कोई तरीका नहीं है।

यह एक उचित डिजाइन की तरह प्रतीत नहीं होता है। क्या एक कारण है कि आपको उसी सॉकेट पर recv() पर कॉल करने वाले दो धागे की आवश्यकता क्यों है?

+0

नहीं, मैं इसे एक परियोजना के लिए स्वयं लागू कर रहा हूं और मैं जानना चाहता था कि – Claudiu

+0

क्या होना चाहिए क्योंकि मैंने पूछा क्योंकि मुझे इसे इस तरह डिजाइन करने का एक अच्छा कारण नहीं दिख रहा है। थ्रेडिंग के लाभों में से एक है हैंडलिंग जैसी सरलताओं को अलग करना है। धागे के बीच एक सॉकेट पर पढ़ना साझा करना इसके बजाय बहुत जटिलता पेश करता है। – dwc

+8

दो धागे से उसी सॉकेट से पढ़ना समझ में आता है अगर यह एक कनेक्शन रहित प्रोटोकॉल जैसे DNS के रूप में यूडीपी सॉकेट है। प्रत्येक थ्रेड तब आने वाले अनुरोधों पर स्वतंत्र रूप से काम करता है। – bdonlan

3

सॉकेट कार्यान्वयन थ्रेड-सुरक्षित होना चाहिए, इसलिए जब उपलब्ध हो तो बिल्कुल एक थ्रेड डेटा प्राप्त करना चाहिए। अन्य कॉल सिर्फ ब्लॉक करना चाहिए।

3

मैं इस के लिए एक संदर्भ नहीं मिल सकता है, लेकिन यहाँ मेरी समझ है:

धागे की सुरक्षा के एक विक्रेता की गारंटी मतलब हो सकता है कि केवल एक से अधिक थ्रेड प्रत्येक सुरक्षित रूप से उनके खुद सॉकेट का उपयोग कर सकते हैं; यह एक ही कॉल में परमाणुता की गारंटी नहीं देता है, और यह एकाधिक धागे के बीच सॉकेट के डेटा के किसी विशेष आवंटन का वादा नहीं करता है।

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

इसके विपरीत, मान लीजिए कि थ्रेड ए को को टीसीपी सॉकेट पर recv() पर कॉल करता है, और डेटा धीरे-धीरे आ रहा है। इसलिए रिकॉर्ड्स() को इग्नो सेट के साथ वापस लौटाता है।

इन मामलों में से किसी एक में, मान लीजिए कि थ्रेड बी उसी सॉकेट पर recv() को कॉल करता है जबकि थ्रेड ए अभी भी डेटा प्राप्त कर रहा है। थ्रेड ए को डेटा सौंपने से रोकता है ताकि थ्रेड बी डेटा प्राप्त करना शुरू कर सके? मुझे यूनिक्स कार्यान्वयन के बारे में पता नहीं है जो याद रखने की कोशिश करेगा कि थ्रेड ए सॉकेट पर ऑपरेशन के बीच में था; इसके बजाए, यह इसके उपयोग पर बातचीत करने के लिए आवेदन (थ्रेड ए और बी) पर निर्भर है।

आम तौर पर, ऐप को डिज़ाइन करना सबसे अच्छा है ताकि धागे में से केवल एक ही सॉकेट पर recv() को कॉल करे।

+0

मुझे लगता है कि आप यहां अपनी धारणाओं के बारे में गलत हैं। recv() को डेटा का एक पैकेट मिलता है और आमतौर पर यूडीपी के साथ प्रयोग किया जाता है, टीसीपी के साथ यह अभी भी डेटा का एक पैकेट प्राप्त करता है, लेकिन जब तक आप प्रेषक पक्ष पर बहुत सावधान नहीं होते हैं, तो आपको एक आरईवी में दो लिखने की सामग्री मिल सकती है। –

+0

ठीक है, मैंने अभी दस्तावेज़ों की जांच की है और यह झंडे के आधार पर एक पैकेट की तुलना में थोड़ा अधिक जटिल है, लेकिन मैंने जो लिनक्स ऐप्स में काम किया है, उसके सामान्य मामले के रूप में मैंने देखा है। –

+0

यूडीपी डेटाग्राम निश्चित रूप से टीसीपी धाराओं wrt धागे से सुरक्षित हैं। मुझे यकीन नहीं है कि वे 100% थ्रेड-सुरक्षित हैं, यद्यपि - यदि आपको एक ईआईएनटीआर मिलता है (क्या यह अभी भी होता है?), तो थ्रेड ए आरईवी() से समय-समय पर रिटर्न देता है, जिससे थ्रेड बी को कूदने का मौका मिलता है। –

2
recv

एक recv() एक SOCK_STREAM सॉकेट पर बफर आपूर्ति पकड़ कर सकते हैं के आकार जितना रिटर्न उपलब्ध जानकारी पर man page से

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

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

अब थ्रेड ए और थ्रेड बी दोनों में अपूर्ण संदेश है, और यह होगा कि कोड कैसे लिखा जाता है, डेटा को अमान्य के रूप में दूर फेंक दें, या अजीब और सूक्ष्म त्रुटियों का कारण बनें।

मेरी इच्छा है कि मैं कह सकता हूं कि मुझे अनुभव से यह नहीं पता था।

तो जबकि आरईवी() स्वयं तकनीकी रूप से थ्रेड सुरक्षित है, तो यह एक बुरा विचार है कि यदि आप इसे टीसीपी के लिए उपयोग कर रहे हैं तो दो धागे इसे एक साथ बुलाएं।

जहां तक ​​मुझे पता है कि जब आप यूडीपी का उपयोग कर रहे हैं तो यह पूरी तरह से सुरक्षित है।

मुझे उम्मीद है कि इससे मदद मिलती है।

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