संसाधन अधिग्रहण आरंभीकरण

संसाधन अधिग्रहण आरंभीकरण है (RAII) एक प्रोग्रामिंग मुहावरा है एक विशेष भाषा के व्यवहार का वर्णन करने के लिए कई ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग|ऑब्जेक्ट-ओरिएंटेड, स्टेटिकली टाइप्ड प्रोग्रामिंग लैंग्वेज|स्टेटिकली-टाइप्ड प्रोग्रामिंग लैंग्वेज में उपयोग किया जाता है। आरएआईआई में, संसाधन धारण करना एक वर्ग अपरिवर्तनीय है, और वस्तु जीवनकाल से बंधा हुआ है। कंस्ट्रक्टर (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) द्वारा ऑब्जेक्ट क्रिएशन (विशेष रूप से इनिशियलाइज़ेशन) के दौरान संसाधन आवंटन (कंप्यूटर) (या अधिग्रहण) किया जाता है, जबकि डिस्ट्रक्टर (कंप्यूटर) द्वारा ऑब्जेक्ट डिस्ट्रक्शन (विशेष रूप से फाइनलाइज़ेशन) के दौरान रिसोर्स डीलोकेशन (रिलीज़) किया जाता है। प्रोग्रामिंग)। दूसरे शब्दों में, सफल होने के लिए आरंभीकरण के लिए संसाधन अधिग्रहण सफल होना चाहिए। इस प्रकार संसाधन को आरंभीकरण समाप्त होने और अंतिम रूप देने के बीच आयोजित होने की गारंटी दी जाती है (संसाधनों को धारण करना एक वर्ग अपरिवर्तनीय है), और वस्तु के जीवित रहने पर ही आयोजित किया जाना है। इस प्रकार, यदि कोई वस्तु लीक नहीं होती है, तो कोई संसाधन रिसाव नहीं होता है।

आरएआईआई सबसे प्रमुख रूप से सी ++ के साथ जुड़ा हुआ है जहां इसकी उत्पत्ति हुई, लेकिन डी (प्रोग्रामिंग भाषा) भी है, एडा (प्रोग्रामिंग भाषा), वाला (प्रोग्रामिंग लैंग्वेज), और जंग (प्रोग्रामिंग भाषा)। सी ++ में अपवाद सुरक्षा | अपवाद-सुरक्षित संसाधन प्रबंधन (कंप्यूटिंग) के लिए तकनीक विकसित की गई थी 1984-89 के दौरान, मुख्य रूप से बज़्ने स्ट्रॉस्ट्रुप और एंड्रयू कोएनिग (प्रोग्रामर) द्वारा, और यह शब्द स्वयं स्ट्रॉस्ट्रुप द्वारा गढ़ा गया था। आरएआईआई को आम तौर पर प्रारंभिकता के रूप में उच्चारित किया जाता है, कभी-कभी आर, ए, डबल आई के रूप में उच्चारित किया जाता है। इस मुहावरे के अन्य नामों में कंस्ट्रक्टर एक्वायर, डिस्ट्रक्टर रिलीज़ (CADRe) शामिल हैं। और उपयोग की एक विशेष शैली को स्कोप-आधारित संसाधन प्रबंधन (एसबीआरएम) कहा जाता है। यह बाद वाला शब्द स्वचालित चर के विशेष मामले के लिए है। RAII संसाधनों को आजीवन वस्तु से जोड़ता है, जो एक दायरे के प्रवेश और निकास के साथ मेल नहीं खा सकता है। (विशेष रूप से फ्री स्टोर पर आवंटित वेरिएबल्स का जीवनकाल किसी भी दायरे से असंबंधित होता है।) हालांकि, स्वचालित चर (SBRM) के लिए RAII का उपयोग करना सबसे आम उपयोग मामला है।

सी ++ 11 उदाहरण
निम्न C++11 उदाहरण फ़ाइल एक्सेस और म्यूटेक्स लॉकिंग के लिए RAII के उपयोग को प्रदर्शित करता है: <वाक्यविन्यास लैंग = सीपीपी>
 * 1) शामिल
 * 2) शामिल
 * 3) शामिल <म्यूटेक्स>
 * 4) शामिल करें
 * 5) शामिल <स्ट्रिंग>

शून्य राइट टूफाइल (स्थिरांक एसटीडी :: स्ट्रिंग और संदेश) { // |म्यूटेक्स| फ़ाइल | तक पहुंच की रक्षा करना है (जो धागे भर में साझा किया जाता है)। स्थिर एसटीडी :: म्युटेक्स म्युटेक्स;

// लॉक | म्यूटेक्स | |फ़ाइल|तक पहुँचने से पहले। एसटीडी :: लॉक_गार्ड <एसटीडी :: म्यूटेक्स> लॉक (म्यूटेक्स);

// फ़ाइल खोलने का प्रयास करें। एसटीडी :: ऑफस्ट्रीम फ़ाइल (example.txt); अगर (! फ़ाइल is_open ) { फेंक std::runtime_error (फ़ाइल खोलने में असमर्थ); }

//लिखें |संदेश| से |फ़ाइल|. फ़ाइल << संदेश << एसटीडी :: endl;

// |फ़ाइल| गुंजाइश छोड़ते समय पहले बंद हो जाएगा (अपवाद की परवाह किए बिना) // |म्यूटेक्स| स्कोप छोड़ते समय दूसरा (लॉक | डिस्ट्रक्टर से) अनलॉक किया जाएगा // (अपवाद की परवाह किए बिना)। } 

यह कोड अपवाद-सुरक्षित है क्योंकि सी ++ गारंटी देता है कि सभी स्टैक ऑब्जेक्ट संलग्न दायरे के अंत में नष्ट हो जाते हैं, जिसे ढेर खोलना कहा जाता है। लॉक और फाइल ऑब्जेक्ट्स दोनों के विनाशकों को फ़ंक्शन से लौटने पर कॉल करने की गारंटी दी जाती है, चाहे कोई अपवाद फेंक दिया गया हो या नहीं। स्थानीय चर एक ही कार्य के भीतर कई संसाधनों के आसान प्रबंधन की अनुमति देते हैं: वे अपने निर्माण के विपरीत क्रम में नष्ट हो जाते हैं, और एक वस्तु केवल पूरी तरह से निर्मित होने पर ही नष्ट हो जाती है - अर्थात, यदि इसके निर्माता से कोई अपवाद नहीं फैलता है। RAII का उपयोग संसाधन प्रबंधन को बहुत सरल करता है, समग्र कोड आकार को कम करता है और कार्यक्रम की शुद्धता सुनिश्चित करने में मदद करता है। RAII इसलिए उद्योग-मानक दिशानिर्देशों द्वारा अनुशंसित है, और अधिकांश सी ++ मानक पुस्तकालय मुहावरे का पालन करते हैं।

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

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

इसलिए संसाधन प्रबंधन को स्वत: आवंटन और सुधार प्राप्त करने के लिए उपयुक्त वस्तुओं के जीवनकाल से जुड़ा होना चाहिए। आरंभीकरण के दौरान संसाधनों का अधिग्रहण किया जाता है, जब उनके उपलब्ध होने से पहले उपयोग किए जाने का कोई मौका नहीं होता है, और उन्हीं वस्तुओं के विनाश के साथ जारी किया जाता है, जो त्रुटियों के मामले में भी होने की गारंटी है।

आरएआईआई की तुलना  जावा में प्रयुक्त निर्माण, स्ट्रॉस्ट्रुप ने लिखा है कि "यथार्थवादी प्रणालियों में, संसाधनों के प्रकारों की तुलना में कहीं अधिक संसाधन अधिग्रहण होते हैं, इसलिए 'संसाधन अधिग्रहण आरंभीकरण है' तकनीक 'आखिरकार' निर्माण के उपयोग की तुलना में कम कोड की ओर ले जाती है।"

विशिष्ट उपयोग
RAII डिज़ाइन का उपयोग अक्सर थ्रेड (कंप्यूटिंग)#मल्टीथ्रेडिंग|मल्टी-थ्रेडेड अनुप्रयोगों में म्यूटेक्स लॉक को नियंत्रित करने के लिए किया जाता है। उस उपयोग में, ऑब्जेक्ट नष्ट होने पर लॉक को रिलीज़ करता है। इस परिदृश्य में RAII के बिना गतिरोध की संभावना अधिक होगी और म्यूटेक्स को लॉक करने का तर्क इसे अनलॉक करने के तर्क से बहुत दूर होगा। आरएआईआई के साथ, म्यूटेक्स को लॉक करने वाले कोड में अनिवार्य रूप से तर्क शामिल है कि निष्पादन आरएआईआई ऑब्जेक्ट के दायरे को छोड़ने पर लॉक जारी किया जाएगा।

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

गतिशील रूप से आवंटित वस्तुओं का स्वामित्व (आवंटित स्मृति  सी ++ में) को आरएआईआई के साथ भी नियंत्रित किया जा सकता है, जैसे कि आरएआईआई (स्टैक-आधारित) ऑब्जेक्ट नष्ट होने पर ऑब्जेक्ट जारी किया जाता है। इस प्रयोजन के लिए, C++11 मानक पुस्तकालय स्मार्ट सूचक वर्गों को परिभाषित करता है   एकल-स्वामित्व वाली वस्तुओं के लिए और   साझा स्वामित्व वाली वस्तुओं के लिए। इसी तरह की कक्षाएं भी उपलब्ध हैं   सी ++ 98 में, और   बूस्ट (सी ++ पुस्तकालय) में।

कंपाइलर क्लीनअप एक्सटेंशन
बजना और जीएनयू कंपाइलर संग्रह दोनों आरएआईआई का समर्थन करने के लिए सी (प्रोग्रामिंग भाषा) भाषा के लिए एक गैर-मानक एक्सटेंशन लागू करते हैं: क्लीनअप वेरिएबल विशेषता। निम्नलिखित एक दिए गए विनाशक फ़ंक्शन के साथ एक वैरिएबल को एनोटेट करता है जिसे वेरिएबल दायरे से बाहर होने पर कॉल करेगा:

<वाक्यविन्यास प्रकाश लैंग = सी> शून्य उदाहरण_उपयोग { __attribute__((क्लीनअप(fclosep))) फ़ाइल *logfile = fopen(logfile.txt, w+); fputs (हैलो लॉगफाइल!, लॉगफाइल); }  इस उदाहरण में, कंपाइलर fclosep फ़ंक्शन को example_usage रिटर्न से पहले लॉगफ़ाइल पर कॉल करने की व्यवस्था करता है।

सीमाएं
आरएआईआई केवल स्टैक-आवंटित वस्तुओं द्वारा अधिग्रहित और जारी (प्रत्यक्ष या अप्रत्यक्ष रूप से) संसाधनों के लिए काम करता है, जहां एक अच्छी तरह से परिभाषित स्थिर वस्तु जीवनकाल है। हीप-आबंटित वस्तुएँ जो स्वयं संसाधनों को प्राप्त और जारी करती हैं, C++ सहित कई भाषाओं में आम हैं। आरएआईआई अपने संसाधन-विमोचन विनाशक (या समतुल्य) को ट्रिगर करने के लिए ढेर-आधारित वस्तुओं पर निर्भर करता है ताकि सभी संभावित निष्पादन पथों के साथ स्पष्ट रूप से या स्पष्ट रूप से हटाया जा सके। चक्रीय रूप से संदर्भित वस्तुओं के लिए कमजोर पॉइंटर्स के साथ, सभी हीप ऑब्जेक्ट्स को प्रबंधित करने के लिए स्मार्ट पॉइंटर्स का उपयोग करके इसे प्राप्त किया जा सकता है।

सी ++ में, स्टैक अनइंडिंग केवल तभी होने की गारंटी है जब अपवाद कहीं पकड़ा जाता है। ऐसा इसलिए है क्योंकि यदि किसी प्रोग्राम में कोई मिलान करने वाला हैंडलर नहीं मिलता है, तो फ़ंक्शन टर्मिनेट कहा जाता है; इस कॉल को समाप्त करने से पहले स्टैक अवांछित है या नहीं  कार्यान्वयन-परिभाषित (15.5.1) है। (सी++03 मानक, §15.3/9)। यह व्यवहार आम तौर पर स्वीकार्य है, क्योंकि ऑपरेटिंग सिस्टम प्रोग्राम समाप्ति पर शेष संसाधन जैसे स्मृति, फ़ाइलें, सॉकेट इत्यादि जारी करता है।

संदर्भ गिनती
पर्ल, पायथन (प्रोग्रामिंग भाषा) (सीपीथॉन कार्यान्वयन में), और पीएचपी संदर्भ गणना द्वारा वस्तु जीवनकाल का प्रबंधन करें, जिससे RAII का उपयोग करना संभव हो जाता है। जिन वस्तुओं को अब संदर्भित नहीं किया जाता है उन्हें तुरंत नष्ट कर दिया जाता है या अंतिम रूप दिया जाता है और जारी किया जाता है, इसलिए एक विध्वंसक या finalizer उस समय संसाधन जारी कर सकता है। हालांकि, यह हमेशा ऐसी भाषाओं में मुहावरेदार नहीं होता है, और विशेष रूप से पायथन में निराश होता है (संदर्भ प्रबंधकों के पक्ष में और कमजोर पैकेज से अंतिम रूप देने वालों के पक्ष में)। हालाँकि, वस्तु जीवन काल अनिवार्य रूप से किसी भी दायरे से बंधे नहीं हैं, और वस्तुओं को गैर-नियतात्मक रूप से नष्ट किया जा सकता है या बिल्कुल भी नहीं। यह गलती से उन संसाधनों को लीक करना संभव बनाता है जिन्हें किसी दायरे के अंत में जारी किया जाना चाहिए था। एक स्थिर चर (विशेष रूप से एक वैश्विक चर) में संग्रहीत वस्तुओं को कार्यक्रम के समाप्त होने पर अंतिम रूप नहीं दिया जा सकता है, इसलिए उनके संसाधन जारी नहीं किए जाते हैं; उदाहरण के लिए, सीपीथॉन ऐसी वस्तुओं को अंतिम रूप देने की कोई गारंटी नहीं देता है। इसके अलावा, परिपत्र संदर्भ वाली वस्तुएं एक साधारण संदर्भ काउंटर द्वारा एकत्र नहीं की जाएंगी, और अनिश्चित रूप से लंबे समय तक जीवित रहेंगी; भले ही एकत्र किया गया हो (अधिक परिष्कृत कचरा संग्रह द्वारा), विनाश का समय और विनाश का क्रम गैर-नियतात्मक होगा। CPython में एक साइकिल डिटेक्टर है जो चक्रों का पता लगाता है और चक्र में वस्तुओं को अंतिम रूप देता है, हालांकि CPython 3.4 से पहले, चक्रों को एकत्र नहीं किया जाता है यदि चक्र में किसी भी वस्तु को अंतिम रूप दिया जाता है।

बाहरी संबंध

 * Sample Chapter: "Gotcha #67: Failure to Employ Resource Acquisition Is Initialization" by Stephen C. Dewhurst
 * Interview: "A Conversation with Bjarne Stroustrup" by Bill Venners
 * Article: "The Law of The Big Two" by Bjorn Karlsson and Matthew Wilson
 * Article: "Implementing the 'Resource Acquisition is Initialization' Idiom" by Danny Kalev
 * Article: "RAII, Dynamic Objects, and Factories in C++" by Roland Pibinger
 * RAII in Delphi: "One-liner RAII in Delphi" by Barry Kelly