के साथ मुझे अपने आवेदन में डेडलॉक्स के साथ एक दिलचस्प समस्या है। एक इन-मेमोरी डेटा स्टोर है जो रीडर्स और लिखने को सिंक्रनाइज़ करने के लिए रीडरवाइटर लॉकस्लिम का उपयोग करता है। पढ़ने के तरीकों में से एक पैरालेल का उपयोग करता है। फ़िल्टर के सेट दिए गए स्टोर को खोजने के लिए। यह संभव है कि फ़िल्टरों में से एक को एक ही स्टोर के निरंतर समय के पढ़ने की आवश्यकता हो। यहां एक परिदृश्य है जो डेडलॉक का उत्पादन कर रहा है:समानांतर में डेडलॉक। ReaderWriterLockSlim
अद्यतन: नीचे उदाहरण कोड। वास्तविक विधि के साथ अद्यतन कदम कॉल
को देखते हुए सिंगलटन उदाहरण ConcreteStoreThatExtendsGenericStore
- की
store
Thread1 दुकान पर एक रीड ताला हो जाता है -store.Update()
- एक लिखने लॉक के साथ दुकान को अद्यतन करने केstore.Search(someCriteria)
- Thread2 प्रयास - , के पीछे ब्लॉक थ्रेड 1
- थ्रेड 1 समानांतर निष्पादित करता है दुकान के खिलाफ orEach फिल्टर
- Thread3 एक निरंतर समय दुकान के पढ़ने के प्रयास करता है (द्वारा Thread1 के Parallel.ForEach पैदा की) का एक सेट चलाने के लिए। यह एक रीड लॉक प्राप्त करने का प्रयास करता है लेकिन थ्रेड 2 के लिखने के लॉक के पीछे अवरुद्ध है।
- थ्रेड 1 समाप्त नहीं हो सकता क्योंकि यह थ्रेड 3 में शामिल नहीं हो सकता है। थ्रेड 2 समाप्त नहीं हो सकता क्योंकि यह थ्रेड 1 के पीछे अवरुद्ध है।
आदर्श रूप में मैं क्या करना चाहते हैं नहीं यदि वर्तमान धागा के एक पूर्वज धागा पहले से ही एक ही ताला है पढ़ने ताला पाने की कोशिश है। क्या इसे करने का कोई तरीका है? या क्या कोई और बेहतर दृष्टिकोण है?
public abstract class GenericStore<TKey, TValue>
{
private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
private List<IFilter> _filters; //contains instance of ExampleOffendingFilter
protected Dictionary<TKey, TValue> Store { get; private set; }
public void Update()
{
_lock.EnterWriterLock();
//update the store
_lock.ExitWriteLock();
}
public TValue GetByKey(TKey key)
{
TValue value;
//TODO don't enter read lock if current thread
//was started by a thread holding this lock
_lock.EnterReadLock();
value = Store[key];
_lock.ExitReadLock();
return value;
}
public List<TValue> Search(Criteria criteria)
{
List<TValue> matches = new List<TValue>();
//TODO don't enter read lock if current thread
//was started by a thread holding this lock
_lock.EnterReadLock();
Parallel.ForEach(Store.Values, item =>
{
bool isMatch = true;
foreach(IFilter filter in _filters)
{
if (!filter.Check(criteria, item))
{
isMatch = false;
break;
}
}
if (isMatch)
{
lock(matches)
{
matches.Add(item);
}
}
});
_lock.ExitReadLock();
return matches;
}
}
public class ExampleOffendingFilter : IFilter
{
private ConcreteStoreThatExtendsGenericStore _sameStore;
public bool Check(Criteria criteria, ConcreteValueType item)
{
_sameStore.GetByKey(item.SomeRelatedProperty);
return trueOrFalse;
}
}
क्या इन-मेमोरी स्टोर एक कस्टम प्रकार है या यह एक सूची है जो कि किसी अन्य श्रेणी के भीतर एक फ़ील्ड है? –
जो आपने फ़ोरैच में चल रहे हैं उसमें लॉक किया है, अन्यथा इसे पढ़ने के बाद समानांतर करना समय की बर्बादी है। समानांतर में कभी भी दौड़ने के लिए नहीं जा रहे हैं क्योंकि वे सभी एक ही संसाधन पर बाधित हैं। –
@TrevorPilley: स्टोर एक शब्दकोश है, समांतर के साथ। मूल्यों के लिए –
eakins05