2010-12-07 13 views
6

मैं कुछ कोड है जो धागा सुरक्षित जिसका व्यवहार होना चाहिए है यह जैसा दिखता है:क्या ताले और इंटरलॉक संचालन को मिश्रण करना सुरक्षित है?

 

protected long m_RunningValue 
protected long m_RunningCounter 
protected object m_Lock = new object(); 

public long RunningValue { get { return Interlocked.Read(m_RunningValue); } } 
public long RunningCounter { get { return Interlocked.Read(m_RunningCounter); } } 

public void DoCalculation(int newValue, int newQuantity) 
{ 
    lock(m_Lock) 
    { 
     Interlocked.Add(ref m_RunningValueA, newValue); 
     Interlocked.Add(ref m_RunningCounter, newQuantity); 
     if(Interlocked.Read(ref newQuantity) == 0) 
     { 
     ...m_RunningValue gets further modified here 
     } 
    } 
} 
 

गणना दोनों मूल्य और काउंटर या एक रेस स्थिति अगर (...) ब्लॉक असर कर सकता है लॉक कर देना चाहिए, लेकिन वे पढ़े जाने पर बिल्कुल सिंक्रनाइज़ करने की आवश्यकता नहीं है, यानी यदि दोनों को पढ़ने के प्रयासों के बीच काउंटर और वैल्यू बदलता है, तो यह मेरे साथ 100% ठीक है।

पढ़ने पर इंटरलॉक 64-बिट मान के थ्रेड-सुरक्षा पढ़ने के लिए है।

  1. इस तरह के इंटरलॉक और ताले मिश्रण करना सुरक्षित है? मैंने उन अन्य वेब पृष्ठों पर पढ़ा है जो उन्हें मिलाकर असुरक्षित हैं, हालांकि मुझे स्पष्टीकरण नहीं मिल रहा है अगर इसका मतलब है कि उन्हें मिलाकर सूक्ष्म बग पेश करने का एक शानदार तरीका है, या यदि सिस्टम स्तर पर यह डेटा संरचनाओं को भ्रष्ट कर सकता है।

  2. क्या इस इंटरलॉकिंग (64-बिट .NET 4.0 रनटाइम) की लागत पूरी तरह से संपत्ति के चारों ओर एक रीडरवाइटर स्लिम लॉक को बचाने के उद्देश्य को हराकर() विधियों को प्राप्त करती है?

+0

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

+0

मुझे कोई कारण नहीं दिख रहा है कि इंटरलॉक किए गए संचालन और ताले मिश्रण क्यों एक समस्या का कारण बनना चाहिए। – casablanca

+0

बस एहसास हुआ कि क्यों Anon का जवाब सच है। यदि आप इंटरलॉक के बिना लॉक के भीतर ऑपरेशन करते हैं, तो क्या आपको संपत्ति को पढ़ने के लिए इंटरलॉक करने की आवश्यकता है? – Chuu

उत्तर

5

के साथ संपादित संस्करण के संबंध में, इस नहीं धागा सुरक्षित होने की गारंटी है।

32-बिट प्लेटफ़ॉर्म पर विचार करें। इसका मतलब है कि दो अलग-अलग परिचालनों में 64-बिट लंबे मूल्यों का उपयोग किया जाना चाहिए।

यह काफी संभव है के लिए एक धागा संख्या की पहली छमाही में पढ़ने के लिए है, तो सीपीयू और अपनी पीठ के पीछे बदल मूल्य की दूसरी छमाही बंद बदली जा। अब उस धागे का एक पूरी तरह से अवैध मूल्य है।

पढ़ें विधि और वृद्धि, घटते क्रम के 64-बिट भार के, और जोड़े तरीकों को सही मायने में केवल सिस्टम जहां एक System.IntPtr 64 है पर परमाणु कर रहे हैं:

Interlocked.Read के लिये दस्तावेज स्पष्ट उल्लेख नहीं है कि बनाने के बिट्स लंबे समय तक। अन्य प्रणालियों पर, ये विधियां एक-दूसरे के संबंध में परमाणु हैं, लेकिन डेटा तक पहुंचने के अन्य साधनों के संबंध में नहीं। इस प्रकार, 32-बिट सिस्टम पर 0 धागा सुरक्षित होने के लिए, किसी भी पहुंच को 64-बिट मान पर इंटरलाक्ड क्लास के सदस्यों के माध्यम से किया जाना चाहिए।

(जोर मेरा)

संपादित करें: अब है कि यह वापस संपादित किया गया है इस एक छोटे से मूर्खतापूर्ण लगता है, लेकिन मैं इसे यहाँ छोड़ मुद्दा यह है कि आप कुछ स्थानों में इंटरलॉकिंग रहे हैं बनाने के लिए की जाती है, लेकिन नहीं दूसरों, यह व्यर्थ है।

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