2010-10-22 20 views
10
lock(dictionaryX) 
{ 
    dictionaryX.TryGetValue(key, out value); 
} 

एक शब्दकोश में लुकअप करते समय आवश्यक लॉकिंग है?शब्दकोश लुकअप के लिए आवश्यक लॉकिंग है?

यह प्रोग्राम बहुप्रचारित है, और कुंजी/कुंजी को मूल्य जोड़ने के दौरान। निर्देश बंद कर दिया जा रहा है।

+1

यदि आपका प्रश्न गंभीर है और बहुप्रचारित कार्यक्रमों का संबंध है, तो कृपया सुनिश्चित करें कि आप स्पष्ट रूप से अपने प्रश्न में उल्लेख करते हैं। –

+3

मेरा प्रश्न आपकी टिप्पणी के रूप में गंभीर नहीं था। लुकअप के लिए भी – DarthVader

उत्तर

2

लॉकिंग केवल तभी जरूरी है जब आप धागे के बीच संसाधन तक पहुंच को सिंक्रनाइज़ कर रहे हों। जब तक नकली धागे शामिल नहीं होते हैं तब तक लॉकिंग की आवश्यकता नहीं होती है।

एकाधिक धागे से मूल्य को अद्यतन करने और पढ़ने के संदर्भ में, हां एक लॉक बिल्कुल जरूरी है। वास्तव में यदि आप 4.0 का उपयोग कर रहे हैं तो आपको विशेष रूप से समवर्ती पहुंच के लिए डिज़ाइन किए गए संग्रहों में से किसी एक पर स्विच करना चाहिए।

+2

? लिखते समय, यह पहले से ही बंद कर दिया जा रहा है। – DarthVader

+1

@ user177883 'डिक्शनरी' पर कोई ऑपरेशन लॉक की आवश्यकता नहीं है जब तक कि – JaredPar

+0

में एकाधिक धागे शामिल न हों, मैंने यह भी बताया कि इसमें डेटा जोड़ने के दौरान शब्दकोश लॉक किया जा रहा है। लेकिन लुकअप करते समय मैं इसे फिर से क्यों बंद कर दूंगा? क्या इसका मतलब है, लिखने के लिए लॉक लॉक होने पर भी मैं लुकअप कर सकता हूं? – DarthVader

0

हां, आपको लॉक करना चाहिए यदि यह शब्दकोश एक से अधिक धागे के बीच एक साझा संसाधन है। यह सुनिश्चित करता है कि आपको सही मूल्य मिलता है और अन्य थ्रेड आपके लुकअप कॉल के दौरान मूल्य को मध्य-मार्ग बदलने के लिए नहीं होता है।

10

जैसा कि बताया जा here:

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

अद्यतन: भी this page की "थ्रेड सुरक्षा" भाग पर एक नज़र डालें।

+0

यह केवल तभी सच है जब थ्रेडिंग शामिल है। थ्रेडिंग के बिना कोई लॉक की आवश्यकता नहीं है। – JaredPar

+3

ओपी ने स्पष्ट रूप से उल्लेख किया कि यह ऑपरेशन एक बहुप्रचारित वातावरण में हो रहा है। –

+1

मैं सहमत हूं। लेकिन सवाल लेखक का मतलब है कि बहु-थ्रेडेड वातावरण में लॉक का उपयोग करना। – Kamyar

1

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

+0

पढ़ने के लिए, पढ़ने के लिए नहीं। – DarthVader

+0

@ user177 हाँ, मैं पढ़ने के बारे में बात कर रहा था। जब मैंने लेखन का उल्लेख किया, तो यह एक उदाहरण है कि जब आप पढ़ने की कोशिश कर रहे हों तो क्या हो सकता है। –

3

प्रोग्रामिंग में कई सूक्ष्म प्रश्नों के साथ, जवाब है: जरूरी नहीं।

यदि आप केवल प्रारंभिक के रूप में मूल्य जोड़ते हैं, तो बाद के पढ़ने को सिंक्रनाइज़ करने की आवश्यकता नहीं है। लेकिन, दूसरी ओर, यदि आप हर समय पढ़ने और लिखने जा रहे हैं, तो बिल्कुल आपको उस संसाधन की रक्षा करने की आवश्यकता है।

हालांकि, एक पूर्ण उड़ा lock आपके शब्दकोश को प्राप्त होने वाले ट्रैफ़िक की मात्रा के आधार पर सबसे अच्छा तरीका नहीं हो सकता है। यदि आप .NET 3.5 या अधिक का उपयोग कर रहे हैं तो ReaderWriterLockSlim आज़माएं।

+2

+1: हालांकि यह एक शॉट के लायक है, यह * बहुत * संभावना है कि 'रीडरवाइटर लॉकस्लिम' इस स्थिति में एक सादे पुराने 'लॉक' से धीमा हो जाएगा ... वास्तव में बहुत धीमी है।अपने स्वयं के व्यक्तिगत परीक्षणों में मैंने पाया है कि 'रीडरवाइटर लॉकस्लिम' में लगभग 5x ओवरहेड है और पुराना 'रीडरवाइटर लॉक' लगभग 15x है। एक आरडब्ल्यू लॉक में सामान्य 'लॉक' की तुलना में एप्लिकेशन की बहुत अधिक संख्या होती है और इस तरह यह ज्यादातर स्थितियों में धीमी हो जाएगी। लॉक लॉक वास्तव में चमकते हैं जब लॉक लंबी अवधि के लिए आयोजित होता है और लेखकों की संख्या व्यापक मार्जिन से पाठकों की संख्या से अधिक होती है। हालांकि यह बेंचमार्किंग के लायक है। –

3

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

if (myDictionary.TryGetValue(key, out value)) 
{ 
} 

और एक अलग थ्रेड यह क्या कर रहा है:

myDictionary.Remove(key); 

क्या हो सकता है धागा TryGetValue कर निर्धारित करता है कि है कि आइटम में है शब्दकोश, लेकिन इससे पहले कि यह आइटम पुनर्प्राप्त कर सके, अन्य धागा इसे हटा देता है।नतीजा यह होगा कि लुकअप करने वाला थ्रेड या तो अपवाद फेंक देगा या TryGetValuetrue लौटाएगा लेकिन valuenull होगा या संभवतः एक ऑब्जेक्ट जो कुंजी से मेल नहीं खाता है।

यह केवल एक चीज है जो हो सकती है। यदि आप एक धागे पर एक लुकअप कर रहे हैं और कोई अन्य धागा उस मूल्य का एक जोड़ करता है जिसे आप देखने की कोशिश कर रहे हैं तो कुछ भी विनाशकारी हो सकता है।

1

यदि आप .Net 4 पर हैं, तो आप सुरक्षित रूप से ऐसा करने के लिए ConcurrentDictionary के साथ प्रतिस्थापित कर सकते हैं। System.Collection.Concurrent namespace में, आपको अन्य समान संग्रह भी पसंद किए जाते हैं, जब आपको बहुप्रचारित पहुंच की आवश्यकता होती है।

रोल-अप-लॉकिंग का उपयोग न करें अगर यह आपके लिए एक विकल्प है।

2

new ConcurrentDictionary<TKey, TValue> object का उपयोग करें और आप किसी भी ताले को करने के बारे में भूल सकते हैं।

+0

आप लॉक के बारे में पूरी तरह से भूल नहीं सकते हैं। यदि आप इसे ConcurrentDictionary पर करते हैं: 'if (concDic.Contains (" key "))' 'concDic [" key "]।(); आप को अपवाद मिल सकता है, क्योंकि इस कुंजी को हटाया जा सकता है अगर और डू() के बीच। – Coder14

0

हां, अगर आपको उस शब्दकोश पर बहुप्रचारित अपडेट हैं तो आपको लॉक करना होगा। जानकारी के लिए इस महान पोस्ट की जाँच करें: “Thread safe” Dictionary(TKey,TValue)

लेकिन ConcurrentDictionary<> शुरू की या तो आप नेट 4 के माध्यम से या 3.5 में Rx का उपयोग कर (यह नया थ्रेड-सुरक्षित संग्रह के लिए कार्यान्वयन के साथ System.Threading.dll शामिल हैं)

से उपयोग कर सकते हैं के बाद से
संबंधित मुद्दे