चमक C++ में ताले के साथ पकड़ने की कोशिश करें




बंद ताले का टोटका (3)

जावा में:

Lock lock = new ReentrantLock();
try{
  lock.lock();
  someFunctionLikelyToCauseAnException();
}
catch(e){...}
finally {
  lock.unlock();
}

मेरा प्रश्न इस उपरोक्त उदाहरण के साथ है, हम जानते हैं कि लॉक विल हमेशा अनलॉक हो जाता है क्योंकि हमेशा निष्पादित होता है, लेकिन सी ++ के साथ क्या गारंटी है?

mutex m;
m.lock();
someFunctionLikelyToCauseAnException();
/// ????

यह कैसे काम करेगा और क्यों?


इसके लिए हम std::lock_guard RAII-style कंस्ट्रक्शन std::lock_guard उपयोग करते हैं। जब आप उपयोग करते हैं

std::mutex m;
{ // start of some scope
    std::lock_guard lg(m);
    // stuff
} // end of scope

lg यह सुनिश्चित करेगा कि m को अनलॉक किया जाएगा कोई बात नहीं है जो गुंजाइश छोड़ दिया गया है क्योंकि यह गुंजाइश से बाहर निकलने और std::lock_guard पर नष्ट हो जाता है std::lock_guard s विध्वंसक कॉल unlock होगा

यहां तक ​​कि अगर एक अपवाद को फेंक दिया जाता है तो स्टैक अनवाउंड ( स्टैक अनइंडिंग ) होगा और यह प्रक्रिया lg को नष्ट कर देती है जो बदले में unlock गारंटी देता है कि लॉक जारी किया गया है।


C ++ के साथ क्या गारंटी है?

C ++ में प्रासंगिक गारंटी जावा में आपके द्वारा उल्लेखित की तुलना में थोड़ी अलग तरह से काम करती है। अंत में ब्लॉक के बजाय, यह स्वचालित चर के विनाश पर निर्भर करता है जो कि स्कोप फ़्रेम के अनपाउंड होने पर स्कोप के बाहर निकलने पर होता है। यह स्कोप अनइंडिंग इस बात की परवाह किए बिना होता है कि स्कोप कैसे निकाला गया, चाहे इनायत हो या अपवाद के कारण।

इस तरह के ताले से संबंधित परिदृश्य के लिए पसंदीदा दृष्टिकोण RAII-style का उपयोग करना है, जैसा कि std::lock_guard द्वारा उदाहरण के लिए लागू किया गया है। यह अपने कंस्ट्रक्टर को पारित किए गए एक mutex ऑब्जेक्ट को रखता है - जिसके अंदर इसे mutex lock() विधि कहते हैं, जिसके बाद थ्रेड म्यूटेक्स का मालिक होता है - और स्कोप अनइंडिंग पर स्कोप के बाहर निकलने पर इसके डिस्ट्रक्टर को कहा जाता है - अंदर जिसे यह mutex unlock() विधि कहता है, इस प्रकार इसे जारी करता है।

कोड इस तरह दिखेगा:

std::mutex m;
{
    std::lock_guard lock(m);
    // Everything here is mutex-protected.
}
// Here you are guaranteed the std::mutex is released.

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

मेरा कहना है: यह कोई भाषा का मुद्दा नहीं है। कोई भी भाषा सुविधा सही त्रुटि से निपटने की गारंटी नहीं दे सकती है। एक चांदी की गोली के रूप में lock_guard और RAII न लें।





locking