सी # में फिर से प्रवेश ताले


119

क्या .NET में C # का उपयोग करते हुए निम्नलिखित कोड का गतिरोध होगा?

 class MyClass
 {
    private object lockObj = new object();

    public void Foo()
    {
        lock(lockObj)
        { 
             Bar();
        }
    }

    public void Bar()
    {
        lock(lockObj)
        { 
          // Do something 
        }
    }       
 }

6
क्या हम इस प्रश्न के शीर्षक को बदलने पर विचार कर सकते हैं - शायद हाल ही में बंद की तरह कुछ करने के लिए ? क्यों नेस्टेड ताले एक गतिरोध का कारण नहीं बनते हैं? जैसा कि यह खड़ा है, शीर्षक लगभग लोगों को इसे खोजने से रोकने के लिए डिज़ाइन किया गया लगता है।
जेफ़ सनाट

12
वास्तव में मुझे यह खोज शब्द 'रीएंन्टेंट' के आधार पर मिला, और इसने मेरे प्रश्न का उत्तर दिया। अगर यह एक कठिन सवाल है, तो यह एक अलग मुद्दा है ...
emfurry

मैं @JeffSternal टिप्पणी से सहमत हूं, यह प्रश्न मानता है कि प्रश्न खोजने वाला व्यक्ति "री-एंट्रेंट" ताले से पहले से परिचित है। एक और दोहराव सवाल मुझे लगता है कि इसके लिए एक अच्छा शीर्षक था: stackoverflow.com/questions/3687505/…
लुइस पेरेज़

जवाबों:


148

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

lock(object) {...}मॉनिटर क्लास का उपयोग करने के लिए आशुलिपि है । जैसा कि मार्क बताते हैं , पुन: प्रवेश कीMonitor अनुमति देता है , इसलिए उस वस्तु पर ताला लगाने का बार-बार प्रयास किया जाता है , जिस पर वर्तमान धागे में पहले से ही ताला लगा हुआ है, यह बहुत ही अच्छा काम करेगा।

यदि आप विभिन्न वस्तुओं पर ताला लगाना शुरू करते हैं, तो आपको सावधान रहना होगा। विशेष ध्यान दें:

  • हमेशा एक ही क्रम में वस्तुओं की संख्या पर ताले प्राप्त करें।
  • हमेशा आप कैसे उन्हें हासिल करने के लिए रिवर्स अनुक्रम में ताले जारी करते हैं।

यदि आप इनमें से किसी भी नियम को तोड़ते हैं, तो आपको कुछ बिंदुओं पर गतिरोध के मुद्दों की गारंटी दी जाती है ।

यहाँ .NET में थ्रेड सिंक्रोनाइज़ेशन का वर्णन करने वाला एक अच्छा वेबपेज है: http://dotnetdebug.net/2005/07/20/monitor-class-avoiding-deadlocks/

इसके अलावा, संभव के रूप में एक समय में कुछ वस्तुओं पर ताला। जहाँ संभव हो मोटे-मोटे ताले लगाने पर विचार करें । यह विचार यह है कि यदि आप अपना कोड ऐसा लिख ​​सकते हैं कि कोई वस्तु ग्राफ़ है और आप उस ऑब्जेक्ट ग्राफ़ के मूल पर ताले प्राप्त कर सकते हैं, तो ऐसा करें। इसका मतलब है कि आपके पास उस रूट ऑब्जेक्ट पर एक लॉक है और इसलिए आपको उस अनुक्रम के बारे में बहुत चिंता करने की ज़रूरत नहीं है जिसमें आप लॉक प्राप्त / रिलीज करते हैं।

(एक और ध्यान दें, आपका उदाहरण तकनीकी रूप से पुनरावर्ती नहीं है। इसे पुनरावर्ती Bar()होने के लिए, आमतौर पर पुनरावृत्ति के भाग के रूप में खुद को कॉल करना होगा।)


1
खासकर अलग-अलग सीक्वेंस में।
मार्क Gravell

6
पुन: पुनरावृत्ति; वास्तव में; लड़का के लाभ के लिए, अवधि फिर से प्रवेशी है
मार्क Gravell

शब्दावली पर स्पष्टीकरण के लिए धन्यवाद - मैंने प्रश्न को संपादित और ठीक किया है।
गइ

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

वास्तव में, मुझे नहीं लगता कि आप जिस क्रम में ताले के मामलों को जारी करते हैं। जिस क्रम में आप उन्हें चुनते हैं वह निश्चित रूप से करता है, लेकिन जब तक ताला जारी किया जाता है तब तक किसी भी चीज पर सशर्त नहीं होता है (आप किसी भी समय जारी कर सकते हैं), आपको तब तक ठीक होना चाहिए जब तक आप उन सभी तालों को छोड़ देते हैं जिन्हें आपने अधिग्रहित किया है।
२०:२० पर bobroxsox

20

खैर, Monitorफिर से प्रवेश करने की अनुमति देता है, तो आप अपने आप को गतिरोध नहीं कर सकते ... तो नहीं: यह नहीं करना चाहिए


7

यदि एक धागा पहले से ही एक ताला लगा रहा है, तो यह खुद को ब्लॉक नहीं करेगा। .Net फ्रेमवर्क यह सुनिश्चित करता है। आपको केवल यह सुनिश्चित करना है कि दो धागे जो भी कोड पथ से एक ही दो तालों को अनुक्रम से बाहर निकालने का प्रयास न करें।

एक ही धागा एक ही लॉक को कई बार एक्वायर कर सकता है, लेकिन आपको यह सुनिश्चित करना होगा कि आप लॉक को उतने ही बार छोड़ें कि आप इसे एक्वायर करें। बेशक, जब तक आप इसे पूरा करने के लिए "लॉक" कीवर्ड का उपयोग कर रहे हैं, यह स्वचालित रूप से होता है।


ध्यान दें कि मॉनिटर के लिए यह सही है, लेकिन जरूरी नहीं कि अन्य प्रकार के लॉक हों।
जॉन स्कीट

(मतलब यह नहीं है कि आप यह नहीं जानते थे कि - बस इतना ही कि यह एक महत्वपूर्ण अंतर है :)
जॉन स्कीट

ये एक अच्छा बिंदु है। मैं वास्तव में "लॉक" को "मॉनिटर" में बदलने वाला था, लेकिन फिर मैं विचलित हो गया। और आलसी। और विंडोज म्यूटेक्स कर्नेल ऑब्जेक्ट के लिए व्यवहार भी सही है, इसलिए मुझे लगा, काफी करीब है!
जेफरी एल व्हाइटलेज

5

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

.. इतने पर और आगे n कुत्तों और मी हड्डियों और अधिक परिष्कृत गतिरोध का कारण।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.