संसाधन अधिग्रहण आरंभीकरण: Difference between revisions
No edit summary |
No edit summary |
||
Line 114: | Line 114: | ||
fputs("hello logfile!", logfile); | fputs("hello logfile!", logfile); | ||
} | } | ||
इस उदाहरण में, कंपाइलर fclosep | इस उदाहरण में, कंपाइलर fclosep प्रोग्राम को उदाहरण_उपयोग रिटर्न से पहले लॉगफ़ाइल पर कॉल करने की व्यवस्था करता है। | ||
== सीमाएं == | == सीमाएं == | ||
आरएआईआई केवल स्टैक-आवंटित वस्तुओं द्वारा अधिग्रहित एवं | आरएआईआई केवल स्टैक-आवंटित वस्तुओं द्वारा अधिग्रहित एवं निरंतर (प्रत्यक्ष या अप्रत्यक्ष रूप से) संसाधनों के लिए कार्य करता है, जहां सही रूप से परिभाषित स्थिर वस्तु जीवनकाल है।हीप-आबंटित वस्तुएँ जो स्वयं संसाधनों को प्राप्त एवं निरंतर करती हैं, C++ सहित कई भाषाओं में सरल हैं। आरएआईआई अपने संसाधन-विमोचन विनाशक (या समतुल्य) को ट्रिगर करने के लिए समूह-आधारित वस्तुओं पर निर्भर करता है जिससे सभी संभावित निष्पादन मार्गो के साथ स्पष्ट रूप से हटाया जा सके।<ref>{{cite news | ||
जहां | |||
| title=Exceptional Situations and Program Reliability | | title=Exceptional Situations and Program Reliability | ||
| first1=Westley | | first1=Westley | ||
Line 129: | Line 127: | ||
| issue=2 | | issue=2 | ||
| year=2008 | | year=2008 | ||
| url=https://web.eecs.umich.edu/~weimerw/p/weimer-toplas2008.pdf}}</ref> | | url=https://web.eecs.umich.edu/~weimerw/p/weimer-toplas2008.pdf}}</ref> चक्रीय रूप से संदर्भित वस्तुओं के लिए कमजोर पॉइंटर्स के साथ, सभी हीप वस्तुओं को प्रबंधित करने के लिए स्मार्ट पॉइंटर्स का उपयोग करके इसे प्राप्त किया जा सकता है। | ||
C ++ में, स्टैक अनइंडिंग केवल तभी होने का आश्वासन देता है जब अपवाद कहीं मिल जाता है। ऐसा इसलिए है क्योंकि यदि किसी प्रोग्राम में कोई मिलान करने वाला हैंडलर नहीं मिलता है, तो प्रोग्राम टर्मिनेट () कहा जाता है; इस आह्वान को समाप्त करने से पूर्व स्टैक अवांछित है या नहीं () कार्यान्वयन-परिभाषित (15.5.1) है। (C++03 मानक, §15.3/9)।<ref>{{cite web | |||
| title=RAII and Stack unwinding | | title=RAII and Stack unwinding | ||
| url=https://stackoverflow.com/a/5557651 | | url=https://stackoverflow.com/a/5557651 | ||
Line 137: | Line 135: | ||
| date=2011-04-05 | | date=2011-04-05 | ||
| publisher=Stack Overflow | | publisher=Stack Overflow | ||
| access-date=2019-03-09}}</ref> यह व्यवहारसामान्यतः स्वीकार्य है, क्योंकि ऑपरेटिंग | | access-date=2019-03-09}}</ref> यह व्यवहारसामान्यतः स्वीकार्य है, क्योंकि ऑपरेटिंग प्रणाली प्रोग्राम समाप्ति पर शेष संसाधन जैसे स्मृति, फ़ाइलें, सॉकेट इत्यादिनिरंतर करता है। | ||
Revision as of 15:46, 26 February 2023
संसाधन अधिग्रहण आरंभीकरण है आरएआईआई (RAII)[1] प्रोग्रामिंग विशिष्ट स्वरूप हैI[2] विशेष भाषा के व्यवहार का वर्णन करने के लिए कई ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग, स्टेटिकली टाइप्ड प्रोग्रामिंग भाषा में उपयोग किया जाता है। आरएआईआई (RAII) में, संसाधन धारण करना वर्ग अपरिवर्तनीय है, एवं वस्तु जीवनकाल से बना हुआ है। कंस्ट्रक्टर (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) द्वारा ऑब्जेक्ट क्रिएशन (विशेष रूप से इनिशियलाइज़ेशन) के समय संसाधन आवंटन (कंप्यूटर) (या अधिग्रहण) किया जाता है, जबकि डिस्ट्रक्टर (कंप्यूटर) द्वारा वस्तु नष्ट (विशेष रूप से फाइनलाइज़ेशन) के समय रिसोर्स डीलोकेशन (रिलीज़) किया जाता है। दूसरे शब्दों में, सफल होने के लिए आरंभीकरण के लिए संसाधन अधिग्रहण सफल होना चाहिए। इस प्रकार संसाधन को आरंभीकरण समाप्त होने एवं अंतिम रूप देने के मध्य आयोजित होने का आश्वासन दिया जाता हैI (संसाधनों को धारण करना वर्ग अपरिवर्तनीय है), एवं वस्तु के जीवित रहने पर ही आयोजित किया जाना है। इस प्रकार, यदि कोई वस्तु लीक नहीं होती है, तो कोई संसाधन रिसाव नहीं होता है।
आरएआईआई (RAII) सबसे प्रमुख रूप से C ++ के साथ जुड़ा हुआ है जहां इसकी उत्पत्ति हुई, लेकिन D (प्रोग्रामिंग भाषा) भी है,[3] एडा (प्रोग्रामिंग भाषा),[4] (प्रोग्रामिंगभाषा),[5] एवं युद्ध (प्रोग्रामिंग भाषा)।[6] C ++ में अपवाद सुरक्षा संसाधन प्रबंधन (कंप्यूटिंग) के लिए प्रौद्योगिकी विकसित की गई थी[7] 1984-89 के समय, मुख्य रूप से बज़्ने स्ट्रॉस्ट्रुप एवं एंड्रयू कोएनिग (प्रोग्रामर) द्वारा,[8] एवं यह शब्द स्वयं स्ट्रॉस्ट्रुप द्वारा बनाया गया था।[9] आरएआईआई को सामान्यतः प्रारंभिकता के रूप में उच्चारित किया जाता है, कभी-कभी "R, A, डबल I" के रूप में उच्चारित किया जाता है।[10] इस विशिष्ट स्वरूप के अन्य नामों में कंस्ट्रक्टर एक्वायर, डिस्ट्रक्टर रिलीज़ (CADRe) सम्मिलित हैं।[11] एवं उपयोग की विशेष शैली को स्कोप-आधारित संसाधन प्रबंधन (एसबीआरएम) कहा जाता है।[12] यह शब्द स्वचालित गतिमान की विशेष स्तिथि के लिए है। (RAII) आरएआईआई संसाधनों को आजीवन वस्तु से जोड़ता है, जो सीमा के प्रवेश एवं निकास के साथ मिल नहीं सकता है। (विशेष रूप से मुफ्त स्टोर पर आवंटित वेरिएबल्स का जीवनकाल किसी भी सीमा से असंबंधित होता है।) चूँकि, स्वचालित गतिमान (SBRM) के लिए आरएआईआई (RAII) को उपयोग करना सबसे सरल स्थिति हैI
C ++ 11 उदाहरण
निम्न C++11 उदाहरण फ़ाइल एक्सेस एवं म्यूटेक्स लॉकिंग के लिए आरएआईआई (RAII) के उपयोग को प्रदर्शित करता है
/#include <fstream>
#include <fstream> #include <mutex> #include <stdexcept> #include <string> void WriteToFile(const std::string& message) { // |mutex| is to protect access to |file| (which is shared across threads). static std::mutex mutex; // Lock |mutex| before accessing |file|. std::lock_guard<std::mutex> lock(mutex); // Try to open file. std::ofstream file("example.txt"); if (!file.is_open()) { throw std::runtime_error("unable to open file"); } // Write |message| to |file|. file << message << std::endl; // |file| will be closed first when leaving scope (regardless of exception) // |mutex| will be unlocked second (from |lock| destructor) when leaving scope // (regardless of exception). }पूर्ण रूप
यह कोड अपवाद-सुरक्षित है क्योंकि C ++ आश्वासन देता है कि सभी स्टैक ऑब्जेक्ट संलग्न सीमा के अंत में नष्ट हो जाते हैं, जिसे उद्घट्टन कहा जाता है। लॉक एवं फाइल ऑब्जेक्ट्स दोनों के विनाशकों को प्रोग्राम से प्रत्यागमन पर आह्वान करने का आश्वासन दिया जाता है, फिर कोई दोषकथन हो अथवा न हो।[13]स्थानीय गतिमान कार्य के अंदर कई संसाधनों के आसान प्रबंधन की अनुमति देते हैं: वे अपने निर्माण के विपरीत क्रम में नष्ट हो जाते हैं, एवं वस्तु केवल पूर्ण रूप से निर्मित होने पर ही नष्ट हो जाती है - अर्थात, यदि इसके निर्माता से कोई दोषारोपण नहीं होताहै।[14] RAII का उपयोग संसाधन प्रबंधन को बहुत सरल करता है, समग्र कोड आकार को कम करता है एवं कार्यक्रम की शुद्धता सुनिश्चित करने में मदद करता है। आरएआईआई (RAII) इसलिए उद्योग-मानक दिशानिर्देशों द्वारा अनुशंसित है,[15] एवं अधिकांश C ++ मानक पुस्तकालय विशिष्ट स्वरूप का पालन करते हैं।[16]
लाभ
संसाधन प्रबंधन प्रौद्योगिकी के रूप में आरएआईआई (RAII) के लाभ यह हैं कि यह कैप्सूलीकरण, अपवाद सुरक्षा (स्टैक संसाधनों के लिए), एवं स्थानीयता प्रदान करता है (यह अधिग्रहण एवं मुक्त करना, तर्क को साथ में लिखने की अनुमति देता है)।
कैप्सूलीकरण प्रदान किया जाता है क्योंकि संसाधन प्रबंधन तर्क को कक्षा में परिभाषित किया जाता है, प्रत्येक आह्वान साइट पर नहीं किया जाता है। स्टैक संसाधनों के लिए अपवाद सुरक्षा प्रदान की जाती है (संसाधन जो उसी सीमा में निरंतर किए जाते हैं जैसे वे अधिग्रहित होते हैं) संसाधन को स्टैक वैरिएबल (किसी दिए गए सीमा में घोषित स्थानीय गतिमान) के जीवनकाल में रखकर: यदि कोई अपवाद हैंडलिंग हटा दी जाती है, एवं उचित अपवाद हैंडलिंग उपस्तिथ है, वर्तमान स्कोप (कंप्यूटर साइंस) से बाहर निकलने पर निष्पादित किया जाने वाला मात्र कोड उस सीमा में घोषित वस्तुओं के विनाशक हैं। अंत में, परिभाषा का स्थान वर्ग परिभाषा में साथ में कंस्ट्रक्टर एवं डिस्ट्रक्टर परिभाषाओं को लिखकर प्रदान किया जाता है।
इसलिए संसाधन प्रबंधन को स्वत: आवंटन एवं सुधार प्राप्त करने के लिए उपयुक्त वस्तुओं के जीवनकाल से जुड़ा होना चाहिए। आरंभीकरण के समय संसाधनों का अधिग्रहण किया जाता है, जब उनके उपलब्ध होने से पूर्व उपयोग किए जाने का कोई संयोग नहीं होता है, एवं उन्हीं वस्तुओं के विनाश के साथ निरंतर किया जाता है।
आरएआईआई की तुलना finally
जावा में प्रयुक्त निर्माण, स्ट्रॉस्ट्रुप ने लिखा है कि "यथार्थवादी प्रणालियों में, संसाधनों के प्रकारों की तुलना में कहीं अधिक संसाधन अधिग्रहण होते हैं, इसलिए 'संसाधन अधिग्रहण आरंभीकरण है ' प्रौद्योगिकी 'अंततः' निर्माण के उपयोग की तुलना में अर्घ्य कोड की ओर ले जाती है।"[1]
विशिष्ट उपयोग
आरएआईआई (RAII) डिज़ाइन का उपयोग प्रायः थ्रेड (कंप्यूटिंग) मल्टी-थ्रेडेड अनुप्रयोगों में म्यूटेक्स लॉक को नियंत्रित करने के लिए किया जाता है। उस उपयोग में, वस्तु नष्ट होने पर लॉक को रिलीज़ करता है। इस परिदृश्य में आरएआईआई (RAII) के बिना गतिरोध की संभावना अधिक होगी एवं म्यूटेक्स को लॉक करने की युक्ति इसे अनलॉक करने की युक्ति से अधिक दूर होगी। आरएआईआई के साथ, म्यूटेक्स को लॉक करने वाले कोड में अनिवार्य रूप से अनुभूति सम्मिलित है कि निष्पादन आरएआईआई ऑब्जेक्ट के सीमा को त्यागने पर लॉक निरंतर किया जाएगा।
अन्य विशिष्ट उदाहरण फाइलों के साथ वार्तालाप कर रहा है: हमारे पास वस्तु हो सकती है जो फ़ाइल का प्रतिनिधित्व करती है जो लिखने के लिए प्रकट हुई है, जिसमें फ़ाइल को कंस्ट्रक्टर में विकसित किया जाता है एवं जब निष्पादन वस्तु सीमा को त्याग देता है तो समाप्त हो जाता है। दोनों ही स्तिथियों में, RAII केवल यह सुनिश्चित करता है कि विचाराधीन संसाधन उचित रूप से निरंतर किया जाए; अपवाद सुरक्षा बनाए रखने के लिए देखभाल की जानी चाहिए। यदि डेटा संरचना या फ़ाइल को संशोधित करने वाला कोड अपवाद-सुरक्षित नहीं है, तो म्यूटेक्स को अनलॉक किया जा सकता है या फ़ाइल को डेटा संरचना के साथ समाप्त किया जा सकता है या फ़ाइल दूषित हो सकती है।
गतिशील रूप से आवंटित वस्तुओं का स्वामित्व (आवंटित स्मृति new
C ++ में) को आरएआईआई के साथ भी नियंत्रित किया जा सकता है, जैसे कि आरएआईआई (स्टैक-आधारित) वस्तु नष्ट होने पर वस्तु निरंतर किया जाता है। इस प्रयोजन के लिए, C++11 मानक पुस्तकालय स्मार्ट सूचक वर्गों को परिभाषित करता है std::unique_ptr
स्वामित्व वाली वस्तुओं के लिए एवं std::shared_ptr
साझा स्वामित्व वाली वस्तुओं के लिए इस प्रकार की कक्षाएं भी उपलब्ध हैं std::auto_ptr
C ++ 98 में, एवं boost::shared_ptr के माध्यम से
बूस्ट (C ++ पुस्तकालय) में भी उपलब्ध हैं।
कंपाइलर क्लीनअप एक्सटेंशन
क्लैंग एवं जीएनयू कंपाइलर संग्रह दोनों आरएआईआई का समर्थन करने के लिए C (प्रोग्रामिंग भाषा) भाषा के लिए अन्य-मानक एक्सटेंशन लागू करते हैं: क्लीनअप वेरिएबल विशेषता [17] निम्नलिखित दिए गए विनाशक प्रोग्राम के साथ वैरिएबल को एनोटेट करता है जिसे वेरिएबल सीमा से बाहर होने पर आह्वान करेगा:
void example_usage() { __attribute__((cleanup(fclosep))) FILE *logfile = fopen("logfile.txt", "w+");
fputs("hello logfile!", logfile); }
इस उदाहरण में, कंपाइलर fclosep प्रोग्राम को उदाहरण_उपयोग रिटर्न से पहले लॉगफ़ाइल पर कॉल करने की व्यवस्था करता है।
सीमाएं
आरएआईआई केवल स्टैक-आवंटित वस्तुओं द्वारा अधिग्रहित एवं निरंतर (प्रत्यक्ष या अप्रत्यक्ष रूप से) संसाधनों के लिए कार्य करता है, जहां सही रूप से परिभाषित स्थिर वस्तु जीवनकाल है।हीप-आबंटित वस्तुएँ जो स्वयं संसाधनों को प्राप्त एवं निरंतर करती हैं, C++ सहित कई भाषाओं में सरल हैं। आरएआईआई अपने संसाधन-विमोचन विनाशक (या समतुल्य) को ट्रिगर करने के लिए समूह-आधारित वस्तुओं पर निर्भर करता है जिससे सभी संभावित निष्पादन मार्गो के साथ स्पष्ट रूप से हटाया जा सके।[18] चक्रीय रूप से संदर्भित वस्तुओं के लिए कमजोर पॉइंटर्स के साथ, सभी हीप वस्तुओं को प्रबंधित करने के लिए स्मार्ट पॉइंटर्स का उपयोग करके इसे प्राप्त किया जा सकता है।
C ++ में, स्टैक अनइंडिंग केवल तभी होने का आश्वासन देता है जब अपवाद कहीं मिल जाता है। ऐसा इसलिए है क्योंकि यदि किसी प्रोग्राम में कोई मिलान करने वाला हैंडलर नहीं मिलता है, तो प्रोग्राम टर्मिनेट () कहा जाता है; इस आह्वान को समाप्त करने से पूर्व स्टैक अवांछित है या नहीं () कार्यान्वयन-परिभाषित (15.5.1) है। (C++03 मानक, §15.3/9)।[19] यह व्यवहारसामान्यतः स्वीकार्य है, क्योंकि ऑपरेटिंग प्रणाली प्रोग्राम समाप्ति पर शेष संसाधन जैसे स्मृति, फ़ाइलें, सॉकेट इत्यादिनिरंतर करता है।
संदर्भ गिनती
पर्ल, पायथन (प्रोग्रामिंग भाषा) (सीपीथॉन कार्यान्वयन में),[20] एवं पीएचपी[21] संदर्भ गणना द्वारा वस्तु जीवनकाल का प्रबंधन करें, जिससे RAII का उपयोग करना संभव हो जाता है। जिन वस्तुओं को अब संदर्भित नहीं किया जाता है उन्हें तुरंत नष्ट कर दिया जाता है या अंतिम रूप दिया जाता है एवं जारी किया जाता है, इसलिए एक विध्वंसक या finalizer उस समय संसाधन जारी कर सकता है। हालांकि, यह हमेशा ऐसी भाषाओं में मुहावरेदार नहीं होता है, एवं विशेष रूप से पायथन में निराश होता है (संदर्भ प्रबंधकों के पक्ष में एवं कमजोर पैकेज से अंतिम रूप देने वालों के पक्ष में)।[citation needed] हालाँकि, वस्तु जीवन काल अनिवार्य रूप से किसी भी दायरे से बंधे नहीं हैं, एवं वस्तुओं को गैर-नियतात्मक रूप से नष्ट किया जा सकता है या बिल्कुल भी नहीं। यह गलती से उन संसाधनों को लीक करना संभव बनाता है जिन्हें किसी दायरे के अंत में जारी किया जाना चाहिए था। एक स्थिर चर (विशेष रूप से एक वैश्विक चर) में संग्रहीत वस्तुओं को कार्यक्रम के समाप्त होने पर अंतिम रूप नहीं दिया जा सकता है, इसलिए उनके संसाधन जारी नहीं किए जाते हैं; उदाहरण के लिए, सीपीथॉन ऐसी वस्तुओं को अंतिम रूप देने की कोई गारंटी नहीं देता है। इसके अलावा, परिपत्र संदर्भ वाली वस्तुएं एक साधारण संदर्भ काउंटर द्वारा एक त्र नहीं की जाएंगी, एवं अनिश्चित रूप से लंबे समय तक जीवित रहेंगी; भले ही एक त्र किया गया हो (अधिक परिष्कृत कचरा संग्रह द्वारा), विनाश का समय एवं विनाश का क्रम गैर-नियतात्मक होगा। CPython में एक साइकिल डिटेक्टर है जो चक्रों का पता लगाता है एवं चक्र में वस्तुओं को अंतिम रूप देता है, हालांकि CPython 3.4 से पहले, चक्रों को एक त्र नहीं किया जाता है यदि चक्र में किसी भी वस्तु को अंतिम रूप दिया जाता है।[22]
संदर्भ
- ↑ 1.0 1.1 Stroustrup, Bjarne (2017-09-30). "Why doesn't C++ provide a "finally" construct?". Retrieved 2019-03-09.
- ↑ Sutter, Herb; Alexandrescu, Andrei (2005). C++ Coding Standards. C++ In-Depth Series. Addison-Wesley. p. 24. ISBN 978-0-321-11358-0.
- ↑ "Scope guards". Dlang Tour. Retrieved 21 May 2021.
- ↑ "Gem #70: The Scope Locks Idiom". AdaCore (in English). Retrieved 21 May 2021.
- ↑ The Valadate Project. "Destruction". The Vala Tutorial version 0.30. Retrieved 21 May 2021.
- ↑ "RAII - Rust By Example". doc.rust-lang.org. Retrieved 2020-11-22.
- ↑ Stroustrup 1994, 16.5 Resource Management, pp. 388–89.
- ↑ Stroustrup 1994, 16.1 Exception Handling: Introduction, pp. 383–84.
- ↑ Stroustrup 1994, p. 389. I called this technique "resource acquisition is initialization."
- ↑ Michael Burr (2008-09-19). "How do you pronounce RAII?". Stack Overflow. Retrieved 2019-03-09.
- ↑ Arthur Tchaikovsky (2012-11-06). "Change official RAII to CADRe". ISO C++ Standard - Future Proposals. Google Groups. Retrieved 2019-03-09.
- ↑ Chou, Allen (2014-10-01). "Scope-Based Resource Management (RAII)". Retrieved 2019-03-09.
- ↑ "How can I handle a destructor that fails?". Standard C++ Foundation. Retrieved 2019-03-09.
- ↑ Richard Smith (2017-03-21). "Working Draft, Standard for ProgrammingLanguage C++" (PDF). Retrieved 2019-03-09.
- ↑ Stroustrup, Bjarne; Sutter, Herb (2020-08-03). "C++ Core Guidelines". Retrieved 2020-08-15.
- ↑ "I have too many try blocks; what can I do about it?". Standard C++ Foundation. Retrieved 2019-03-09.
- ↑ "Specifying Attributes of Variables". Using the GNU Compiler Collection (GCC). GNU Project. Retrieved 2019-03-09.
- ↑ Weimer, Westley; Necula, George C. (2008). "Exceptional Situations and Program Reliability" (PDF). ACM Transactions on Programming Languages and Systems. Vol. 30, no. 2.
- ↑ ildjarn (2011-04-05). "RAII and Stack unwinding". Stack Overflow. Retrieved 2019-03-09.
- ↑ "Extending Python with C or C++: Reference Counts". Extending and Embedding the Python Interpreter. Python Software Foundation. Retrieved 2019-03-09.
- ↑ hobbs (2011-02-08). "Does PHP support the RAII pattern? How?". Retrieved 2019-03-09.
- ↑ "gc — Garbage Collector interface". The Python Standard Library. Python Software Foundation. Retrieved 2019-03-09.
अग्रिम पठन
- Stroustrup, Bjarne (1994). The Design and Evolution of C++. Addison-Wesley. Bibcode:1994dec..book.....S. ISBN 978-0-201-54330-8.
बाहरी संबंध
- 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