2012-03-25 38 views
5

क्या यह सुरक्षित है अगर मैं एक सर्वर सॉकेट पर 1 थ्रेड से closesocket() को कॉल करना चाहता हूं जो एक अन्य थ्रेड से अलग है जो सर्वर को उसी सर्वर सॉकेट का उपयोग कर चलाता है?क्या closesocket धागा सुरक्षित है?

+2

आप फिर से सोचना चाहेंगे * क्यों * आपके पास एक ही सॉकेट तक पहुंचने वाले एकाधिक थ्रेड हैं। शायद कुछ राज्य ध्वज होना बेहतर हो सकता है जो * अन्य धागे को सूचित कर सकता है जो एक कनेक्शन मर रहा है, लेकिन केवल एक थ्रेड वास्तव में सॉकेट के साथ बातचीत करता है। –

+0

@KerrekSB - आमतौर पर, सॉकेट तक पहुंचने वाले एक से अधिक थ्रेड होते हैं क्योंकि एक थ्रेड पढ़ने को अवरुद्ध करता है और दूसरा थ्रेड लिखता है। यह सुरक्षित/सामान्य है। यदि थ्रेड/एस कॉल अवरुद्ध करने पर फंस गए हैं तो एक राज्य ध्वज उपयोगी नहीं है। –

+0

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

उत्तर

5

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

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

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

+0

यही है 'TIME_WAIT' के लिए है। यदि कुछ उच्च स्तरीय मैपिंग है, (उदाहरण के लिए, सॉकेट लाइब्रेरी सॉकेट संदर्भ ऑब्जेक्ट आवंटित करती है), और यह सुनिश्चित करने में विफल रहता है कि ऐसे संदर्भों का पुन: उपयोग नहीं किया जा सकता है, जो ओपी प्रश्न के दायरे में नहीं है। यदि इस दृष्टिकोण को गलत माना जाता है, तो हो सकता है कि कोई व्यक्ति वैकल्पिक विकल्प सुझाए, (जिसमें एक सिंक सर्वर के रूप में एक सिंक सर्वर का एक नया स्वरूप शामिल नहीं है और ध्वज की जांच करने के लिए सॉकेट पर सीपीयू-बर्बाद शॉर्ट टाइमआउट की आवश्यकता नहीं है)। –

+1

नहीं, यह 'TIME_WAIT' से पूरी तरह से असंबंधित है। मैं * पोर्ट * के पुन: उपयोग के बारे में बात नहीं कर रहा हूं, जो कोई समस्या नहीं है। मैं * सॉकेट नंबर * के बारे में बात कर रहा हूं (पॉज़िक्स पर यह एक फ़ाइल डिस्क्रिप्टर होगा, लेकिन विंडोज़ पर वे अलग हैं), जो एक खुली सॉकेट की पहचान करने वाली प्रक्रिया के लिए एक पूर्णांक स्थानीय है, जिसका पुन: उपयोग किया जा रहा है। इसका 'TIME_WAIT' के साथ बिल्कुल कुछ नहीं है। –

+0

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

1

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