2011-02-17 34 views
38

संभव डुप्लिकेट:
Re-entrant locks in C#नेस्टेड ताले क्यों डेडलॉक का कारण नहीं बनते हैं?

क्यों इस कोड को एक गतिरोध का कारण नहीं है?

private static readonly object a = new object(); 

...

lock(a) 
    { 
     lock(a) 
     { 
     .... 
     } 
    } 
+0

आप इसे डेडलॉक क्यों करने की उम्मीद कर रहे हैं? (यह भी, http://stackoverflow.com/questions/391913/re-entrant-locks-in-c के समान है जो मदद कर सकता है) – AakashM

+3

यह स्पष्ट रूप से इसका एक डुप्लिकेट है, लेकिन यह प्रश्न का शीर्षक असीम रूप से बेहतर है (उन लोगों के लिए जो शायद इसकी तलाश करेंगे)। –

उत्तर

34

यदि कोई थ्रेड पहले से ही लॉक रखता है, तो यह बिना किसी समस्या के "उस लॉक को" ले सकता है।


रूप क्यों कि है, (और क्यों यह एक अच्छा विचार है), तो निम्न स्थिति, जहां हम एक परिभाषित ताला एक के कार्यक्रम में कहीं और आदेश देने पर विचार किया है -> ख:

void f() 
{ 
    lock(a) 
    { /* do stuff inside a */ } 
} 

void doStuff() 
{ 
    lock(b) 
    { 
     //do stuff inside b, that involves leaving b in an inconsistent state 
     f(); 
     //do more stuff inside b so that its consistent again 
    } 
} 

ओह, हमने अभी हमारे लॉक ऑर्डरिंग का उल्लंघन किया है और हमारे हाथों पर संभावित डेडलॉक है।

हम वास्तव में निम्न करने के लिए सक्षम होना चाहिए :

function doStuff() 
{ 
    lock(a) 
    lock(b) 
    { 
     //do stuff inside b, that involves leaving b in an inconsistent state 
     f(); 
     //do more stuff inside b so that its consistent again 
    } 
} 

ताकि हमारे ताला आदेश बनाए रखा है, बिना आत्म deadlocking हम पर कब कॉल f()

+1

+1 क्यों और एक अच्छा उदाहरण जब आप सुविधा का उपयोग करेंगे। – Myster

+0

क्या आप समझा सकते हैं कि डेडलॉक क्यों है? आपका लॉक ऑर्डरिंग मेरे लिए संगत लगता है। सभी कोड पथ लॉक ए या बी-> ए को लॉक करने के लिए कोई कोड पथ नहीं है-> बी –

+1

@ जेरेडकेल्स इसे पहले कोड ब्लॉक से पहले परिभाषित किया गया है; .... जहां हमारे पास प्रोग्राम में कहीं और परिभाषित लॉक ऑर्डरिंग ** है -> बी: – Mr47

18

lock कीवर्ड, एक फिर से प्रवेशी ताला का उपयोग करता है, जिसका अर्थ है वर्तमान धागा पहले से ही ताला है तो यह यह पुनः प्राप्त करने के लिए प्रयास नहीं करता है।

एक गतिरोध अगर

थ्रेड 1 अर्जित एक
थ्रेड लॉक होता है 2 अर्जित ताला बी
धागा ताला बी (यह के साथ किया जा करने के लिए धागा 2 के लिए प्रतीक्षा करता है) थ्रेड प्राप्त करने के लिए 2 की कोशिश करता प्राप्त करने के लिए 1 की कोशिश करता लॉक ए (इसके साथ थ्रेड 1 के लिए इंतजार कर रहा है)

दोनों धागे अब एक-दूसरे पर इंतजार कर रहे हैं और इस प्रकार मृतक हैं।

+0

गैर-पुनर्वित्तक लॉक का उदाहरण ढूंढने का प्रयास कर रहा है, लेकिन Google मुझे विफल कर रहा है। – Davy8

+1

[रीडरवाइटर लॉकस्लिम] (http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlockslim%28v=vs.110%29.aspx) एक उदाहरण है। – Chuu

8
सी # भाषा विनिर्देशन का section 8.12 से

:

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

यह स्पष्ट होना चाहिए कि आंतरिक lock गुंजाइश बाहरी के समान धागे में है।

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