2011-01-26 20 views
6

का उपयोग करने का उचित तरीका यह दो सूची (टी) ऑब्जेक्ट्स को लॉक करने के संबंध में previous question पर एक फॉलो-अप है। जवाब वहां सहायक था लेकिन मुझे एक और सवाल के साथ छोड़ दिया।सिंकलॉक (सामान्य रूप से)

मान लीजिए मैं इस तरह एक समारोह है:

Public Function ListWork() As Integer 
    List1.Clear() 
    ..Some other work which does not modify List1.. 
    List1.AddRange(SomeArray) 
    ..Some more work that does not involve List1.. 
    Retrun List1.Count 
End Function 

जो एक वर्ग है कि List1 वाणी में रहता है। एक बहुप्रचारित वातावरण में, अब मैं समझता हूं कि मेरे पास सूची 1 के लिए एक निजी लॉकिंग ऑब्जेक्ट होना चाहिए और जब भी यह संशोधित या गणना की जाती है तो सूची 1 लॉक करें। मेरा प्रश्न है, मैं इस करना चाहिए:

Private List1Lock As New Object 
Public Function ListWork() As Integer 
    SyncLock List1Lock 
    List1.Clear() 
    ..Some other work which does not modify List1.. 
    List1.AddRange(SomeArray) 
    ..Some more work that does not involve List1.. 
    Dim list1Count As Integer = List1.Count 
    End SyncLock 
    Retrun list1Count 
End Function 

मेरा अनुमान है कि यह है कि पूर्व उदाहरण इष्टतम है:

Private List1Lock As New Object 
Public Function ListWork() As Integer 
    SyncLock List1Lock 
    List1.Clear() 
    End SyncLock 
    ..Some other work which does not modify List1.. 
    SyncLock List1Lock 
    List1.AddRange(SomeArray) 
    End SyncLock 
    ..Some more work that does not involve List1.. 
    SyncLock List1Lock 
    Dim list1Count As Integer = List1.Count 
    End SyncLock 
    Retrun list1Count 
End Function 

या है?

उत्तर

9

उदाहरणों से, यह कहना मुश्किल है कि कौन सा सही है, यदि कोई है तो। कुछ दिशानिर्देश/टिप्पणियां हालांकि इससे आपको अपने प्रश्न का उत्तर देने में मदद मिल सकती है, या पता है कि अतिरिक्त जानकारी के लिए क्या प्रदान करना है:

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

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

सामान्य रूप से सिंक्रनाइज़ेशन/लॉकिंग के बारे में: यदि आपके ऑपरेशन को चरणों के बीच बाधित किया गया था, तो क्या डेटा लगातार/मान्य होगा?

अपने उदाहरण में, कहें कि आपके पास दो धागे हैं। पहला क्षेत्र .AddRange() और .Count के बीच क्षेत्र में है, जब दूसरा धागा फ़ंक्शन में प्रवेश करता है, और सूची में लॉक प्राप्त करता है।

थ्रेड 1 थोड़ा और चलता है, और लॉक को .Count विधि की सुरक्षा करता है, और सो जाता है। इस बीच थ्रेड 2 सूची को साफ़ करता है और फिर अपने लॉक को रिलीज़ करता है, थ्रेड 1 अप जागता है, जो तब लॉक प्राप्त करता है।

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

इस मामले में, अलग-अलग सूची संचालन के आसपास ताले कार्यक्रम को तोड़ते हैं, इसलिए Clear और Count कॉल के बीच एक लॉक होने का अधिक अर्थ होता है।

संक्षेप में, बहु-थ्रेडिंग Race Conditions से संबंधित सूक्ष्म बग की पूरी कक्षा को पेश करने का एक अच्छा तरीका है, जिसका परिणाम Heisenbugs होता है।

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

उम्मीद है कि यह आपको बहु-थ्रेडेड कोड में भविष्य के रोमांच के लिए हाथ में मदद करता है।

+0

मुझे लगता है कि मैं इसे अब समझता हूं। बहुत सूक्ष्म। मुझे कक्षा या कुछ लेना चाहिए ... अंतर्दृष्टि के लिए धन्यवाद। –

6

"यह निर्भर करता है"। दो उदाहरणों में अलग-अलग अर्थशास्त्र हैं।

बाद के उदाहरण में लॉक लॉक के संबंध में संचालन का पूरा सेट परमाणु है। जबकि पूर्व उदाहरण में सूची में प्रवेश लॉक में संरक्षित है, लेकिन संचालन के पूरे सेट को लॉक लॉक के संबंध में परमाणु () के रूप में देखा जा सकता है।

कल्पना कीजिए कि/मामले में हो सकता है होता अगर आपरेशन/धागा interleaving अगर ListWork अलग धागे द्वारा एक ही वस्तु पर लागू किया गया था।

हैप्पी कोडिंग।

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