2009-12-22 16 views
15

मैं सी # में संग्रह के पीछे थ्रेड सुरक्षा सिद्धांत का एक अवलोकन प्राप्त करने की कोशिश कर रहा हूं।सी # में कोई समवर्ती संग्रह क्यों नहीं हैं?

जावा में मौजूद कोई समवर्ती संग्रह क्यों नहीं हैं? (java docs)। कुछ संग्रह धागा सुरक्षित दिखाई देते हैं लेकिन यह मेरे लिए स्पष्ट नहीं है क्या स्थिति के संबंध में उदाहरण के लिए है:

  • यौगिक संचालन, iterators का उपयोग करने का
  • सुरक्षा,
  • लिखने के संचालन

मैं पहिया को फिर से शुरू नहीं करना चाहता! (मैं एक बहु-थ्रेडिंग गुरु नहीं हूं और निश्चित रूप से कम आकलन नहीं कर रहा हूं कि यह वैसे भी कितना मुश्किल होगा)।

मुझे आशा है कि समुदाय सहायता कर सकता है।

+0

ग्रेट प्रतिक्रिया - मैं रडार पर रखने के लिए थोड़ी देर के लिए यह 'अनुत्तरित' छोड़ दूंगा। अगर किसी के पास या तो इस विषय पर खेलने के नेट या पोस्ट पर लेखों के लिए कोई और लिंक है तो कृपया शामिल करें। आप सभी को धन्यवाद। – Andrew

उत्तर

28

नेट अब तक अपेक्षाकृत "कम स्तर" संगामिति समर्थन किया गया है - लेकिन .NET 4.0 System.Collections.Concurrent नाम स्थान है जो विभिन्न संग्रह जो सुरक्षित और उपयोगी होती हैं परिचय देता है।

एंड्रयू जवाब कैसे निश्चित रूप से .NET 4.0 से पहले संग्रह से निपटने के लिए के मामले में पूरी तरह से सही है - और के लिए सबसे जब एक "सामान्य" साझा संग्रह तक पहुँचने मैं सिर्फ उचित रूप से लॉक होता उपयोग करता है। समवर्ती संग्रह, हालांकि, निर्माता/उपभोक्ता कतार, आदि का उपयोग करना आसान बनाता है

+0

+1 धन्यवाद जॉन। मुझे लगता है कि इस तरह से .net लोगों को सुरक्षितता की झूठी भावना में नहीं खोता है। मैं नेट 4.0 उपहारों की जांच करूंगा। - एंड्रयू – Andrew

+0

+1 अच्छा, उस बारे में सब भूल गया :) –

19

सी # कई धागे में संग्रह के साथ काम करने के कई तरीके प्रदान करता है। इन तकनीकों का एक अच्छा लेख के लिए मैं सुझाव है कि आप Collections and Synchronization (Thread Safety) के साथ शुरू:

डिफ़ॉल्ट रूप से, संग्रह कक्षाएं आम तौर पर सुरक्षित थ्रेड नहीं हैं। एकाधिक पाठक आत्मविश्वास के साथ संग्रह को पढ़ सकते हैं; हालांकि, संग्रह में किसी भी संशोधन को परिणामों को तक पहुंचने वाले सभी थ्रेड के लिए परिणाम प्रस्तुत करता है, जिसमें पाठक धागे शामिल हैं।

संग्रह वर्गों निम्नलिखित से किसी भी विधि का उपयोग कर धागा सुरक्षित बनाया जा सकता है:

  • सिंक्रनाइज़ पद्धति का उपयोग करके एक धागा सुरक्षित आवरण बनाएँ, और पहुँच संग्रह विशेष रूप से है कि आवरण के माध्यम से ।
  • यदि कक्षा में सिंक्रनाइज़ विधि नहीं है, तो कक्षा से प्राप्त करें और सिंक्रनाइज़ सिंक्रूट संपत्ति का उपयोग कर विधि लागू करें।
  • संग्रह तक पहुंचने पर सिंक्रूट संपत्ति पर, सी # (सिंकलॉक विजुअल बेसिक) में लॉक स्टेटमेंट जैसे लॉक स्टेटमेंट का उपयोग करें।
+0

+1 जो तेज़ था! - यह जावा से Collections.synchronizedList की तरह थोड़ा दिखता है। मैं उस लिंक को देख लूंगा। धन्यवाद – Andrew

+4

और यहां भी देखें: http://blogs.msdn.com/ericlippert/archive/2008/01/21/immutability-in-c-part-nine-academic-plus-my-avl-tree-implementation.aspx जहां एरिक लिपर्ट कुछ गहराई में अपरिवर्तनीय संग्रह पर चर्चा करता है, विशेष रूप से समवर्ती पहुंच के संबंध में। –

+0

धन्यवाद जेरेमी इस ब्लॉग के पार नहीं आया था (अब सदस्यता लें) अपरिवर्तनीय टैग के तहत कुछ उत्कृष्ट सामग्री है। – Andrew

6

जैसा कि जॉन स्कीट ने उल्लेख किया है, अब सिस्टम में "थ्रेड सुरक्षित" संग्रह हैं। चयन। .NET 4.Concurrent नेमस्पेस .NET 4.

में

एक कारण यह है कि पहले से कोई समवर्ती संग्रह मौजूद नहीं है (कम से कम मेरा अनुमान)।नेट फ्रेमवर्क संस्करण यह है कि एक समवर्ती संग्रह के साथ भी थ्रेड सुरक्षा की गारंटी देना बहुत मुश्किल है।

(यह पूरी तरह सच नहीं है के रूप में कुछ संग्रह एक सिंक्रनाइज़ विधि की पेशकश एक गैर धागा सुरक्षित संग्रह से एक धागा सुरक्षित संग्रह लौटने के लिए तो वहाँ कुछ धागा सुरक्षित संग्रह हैं ...)

उदाहरण के लिए मान गई है एक धागा सुरक्षित शब्दकोश - यदि कोई कुंजी केवल मौजूद नहीं है, तो कुंजी मौजूद नहीं है, तो पहले यह देखने के लिए संग्रह से पूछताछ करेगा कि कुंजी मौजूद है या नहीं, तो कुंजी मौजूद नहीं होने पर कोई डालने वाला होगा। हालांकि, ये दो ऑपरेशन थ्रेड सुरक्षित नहीं हैं, कंटेनकी और क्वेरी ऑपरेशन की क्वेरी के बीच एक और धागा उस कुंजी का एक सम्मिलन कर सकता था इसलिए दौड़ की स्थिति होती है।

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

+0

मैं उसी पंक्ति के साथ सोच रहा था। पुट-ए-अनुपस्थित मुद्दा जहां आप अपने संग्रह में 2 ऑब्जेक्ट्स के साथ समाप्त कर सकते हैं जहां पहले कोई नहीं था। धन्यवाद +1। – Andrew

+0

@saret: वास्तव में, वास्तव में कितना मुश्किल है, वास्तविक थ्रेड-सुरक्षित उपयोग के लिए आवश्यक कार्यों को प्रदान करना? मुझे लगता है कि अगर शब्दकोश को "कुछ भी नहीं" मान रखने की आवश्यकता नहीं है, तो सबकुछ एक गणक के साथ किया जा सकता है, एक लंबी परिवर्तन-गिनती संपत्ति, और एक विधि जो थ्रेडिंग के समान काम करती है .Interlocked.CompareExchange। "कुछ भी नहीं" मूल्य जोड़ना थोड़ा और जटिलता बनाता है, लेकिन बहुत अधिक नहीं। – supercat

+0

@supercat, संभावित रूप से बेहतर तरीका संग्रह पर विधियों की पेशकश करना है जो लॉक के भीतर काम करते हैं (जैसे कि लॉक के भीतर क्रिया/निष्पादन निष्पादित करें), या InsertIfNotExists – saret

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