संसाधन प्रबंधन (कंप्यूटिंग)

From alpha
Jump to navigation Jump to search

कंप्यूटर प्रोग्रामिंग में, संसाधन प्रबंधन सिस्टम संसाधन (सीमित उपलब्धता वाले घटक) के प्रबंधन के लिए तकनीकों को संदर्भित करता है।

कंप्यूटर प्रोग्राम अपने स्वयं के संसाधनों का प्रबंधन कर सकते हैं प्रोग्रामिंग लैंग्वेज विभिन्न दृष्टिकोणों के विपरीत एक सर्वेक्षण लेख है) द्वारा प्रदर्शित सुविधाओं का उपयोग करके, या उन्हें एक होस्ट - एक ऑपरेटिंग सिस्टम या वर्चुअल मशीन - या किसी अन्य प्रोग्राम द्वारा प्रबंधित करने का चुनाव कर सकता है।

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

नियंत्रक अभिगम

जब किसी प्रोग्राम का उपयोग करना समाप्त हो जाता है तो संसाधन को जारी करने की चूक को संसाधन क्षरण (रिसोर्स लीक) के रूप में जाना जाता है, और अनुक्रमिक कंप्यूटिंग में एक समस्या है। एक सीमित संसाधन तक पहुँचने के लिए कई प्रक्रियाएँ समवर्ती कंप्यूटिंग में एक समस्या हो सकती हैं, और इसे संसाधन विवाद के रूप में जाना जाता है।

संसाधन प्रबंधन इन दोनों स्थितियों को रोकने के लिए अभिगम को नियंत्रित करने का प्रयास करता है।

रिसोर्स लीक

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

हालाँकि, संसाधन प्रबंधन सबसे अधिक उद्धृत अनुप्रयोग है। आस्पेक्ट-ओरिएंटेड प्रोग्रामिंग में, लॉजिक के चारों ओर ऐसा निष्पादन सूचना का एक रूप है।

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

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

मेमोरी मैनेजमेंट

मेमोरी को एक संसाधन के रूप में माना जा सकता है, लेकिन मेमोरी प्रबंधन को सामान्यतौर पर अलग से माना जाता है, मुख्यतः क्योंकि स्मृति आवंटन और डीलोकेशन फ़ाइल हैंडल जैसे अन्य संसाधनों के अधिग्रहण और रिलीज की तुलना में काफी अधिक होता है। बाहरी सिस्टम द्वारा प्रबंधित मेमोरी में (आंतरिक) मेमोरी प्रबंधन (चूंकि यह मेमोरी है) और संसाधन प्रबंधन (चूंकि यह बाहरी सिस्टम द्वारा प्रबंधित किया जाता है) दोनों में समानता है। उदाहरणों में नेटिव कोड के माध्यम से प्रबंधित और जावा से उपयोग की जाने वाली मेमोरी सम्मिलित है ( जावा नेटिव इंटरफ़ेस के माध्यम से); और जावास्क्रिप्ट से उपयोग किए गए दस्तावेज़ ऑब्जेक्ट मॉडल (डीओएम) में ऑब्जेक्ट। इन दोनों मामलों में, रनटाइम वातावरण (वर्चुअल मशीन) का मेमोरी मैनेजर (गारबेज कलेक्टर) बाहरी मेमोरी को प्रबंधित करने में असमर्थ है (कोई साझा मेमोरी प्रबंधन नहीं है), और इस प्रकार बाहरी मेमोरी को एक संसाधन के रूप में माना जाता है, और समान रूप से प्रबंधित किया जाता है। . हालाँकि, सिस्टम के बीच चक्र (जावास्क्रिप्ट DOM का संदर्भ देता है, जावास्क्रिप्ट का संदर्भ देता है) प्रबंधन को कठिन या असंभव बना सकता है।

शाब्दिक प्रबंधन और स्पष्ट प्रबंधन

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

मूलभूत तकनीकें

संसाधन प्रबंधन के लिए मूल दृष्टिकोण एक संसाधन प्राप्त करना है, इसके साथ कुछ करना है, फिर इसे जारी करना है, फॉर्म का कोड देना (पायथन में फ़ाइल खोलने के साथ सचित्र):

f = open(filename)
...
f.close()

यह सही है अगर हस्तक्षेप करने वाले ... कोड में प्रारंभिक निकास ( return ) नहीं है, भाषा में अपवाद नहीं open, और सफल होने की गारंटी है। हालाँकि, यदि रिटर्न या अपवाद होता है, तो यह संसाधन रिसाव का कारण बनता है, और यदि open विफल हो सकता है, तो अप्राप्त संसाधन की गलत रिलीज़ का कारण बनता है।

यह सही है अगर हस्तक्षेप करने वाले ... कोड में प्रारंभिक निकास (return) नहीं है, भाषा में अपवाद नहीं open, और सफल होने की गारंटी है। हालाँकि, यदि रिटर्न या अपवाद होता है, तो यह संसाधन रिसाव का कारण बनता है, और यदि open विफल हो सकता है, तो अप्राप्त संसाधन की गलत रिलीज़ का कारण बनता है।

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

f = open(filename)
try:
    ...
finally:
    f.close()


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

f = open(filename)
try:
    ...
finally:
    if f:
        f.close()

जबकि यह सही संसाधन प्रबंधन सुनिश्चित करता है, यह निकटता या एनकैप्सुलेशन प्रदान करने में विफल रहता है। कई भाषाओं में ऐसे तंत्र हैं जो इनकैप्सुलेशन प्रदान करते हैं, जैसे कि पायथन में कथन के with :

with open(filename) as f:
    ...

उपरोक्त तकनीकें - अनवाइंड प्रोटेक्शन ( finally ) और एनकैप्सुलेशन के कुछ रूप - संसाधन प्रबंधन के लिए सबसे सामान्य दृष्टिकोण हैं, जो C#, कॉमन लिस्प, जावा, पायथन, रूबी, स्कीम और स्मॉलटॉक, [1] में विभिन्न रूपों में पाए जाते हैं। ; वे लिस्प की NIL बोली में 1970 के दशक के उत्तरार्ध में हैं; अपवाद प्रबंधन § इतिहास । कान्वयन में कई विविधताएँ हैं, और काफी भिन्न दृष्टिकोण भी हैं।


दृष्टिकोण (अप्प्रोचेस)

उनविंड सुरक्षा

सभी भाषाओं में संसाधन प्रबंधन के लिए सबसे सामान्य दृष्टिकोण सुरक्षा का उपयोग करना है, जिसे तब कहा जाता है जब निष्पादन एक दायरे से बाहर निकलता है - ब्लॉक के अंत में निष्पादन द्वारा, ब्लॉक के भीतर से वापस आने पर, या एक अपवाद फेंके जाने पर। यह स्टैक-प्रबंधित संसाधनों के लिए काम करता है, और C#, कॉमन लिस्प, जावा, पायथन, रूबी और स्कीम सहित कई भाषाओं में लागू किया गया है। इस दृष्टिकोण के साथ मुख्य समस्या यह है कि रिलीज कोड (सामान्यतौर पर finally क्लॉज में) अधिग्रहण कोड से बहुत दूर हो सकता है (इसमें निकटता की कमी है), और यह कि अधिग्रहण और रिलीज कोड को हमेशा कॉलर द्वारा जोड़ा जाना चाहिए (इसमें कमी है) एनकैप्सुलेशन )। क्लोजर / कॉलबैक / कॉरआउट्स का उपयोग करके, या अधिग्रहण और रिलीज दोनों को संभालने वाली वस्तु का उपयोग करके, और इन तरीकों को कॉल करने के लिए एक भाषा निर्माण जोड़कर, जब नियंत्रण एक दायरे में प्रवेश करता है और बाहर निकलता है, तो इसे या तो कार्यात्मक रूप से उपचारित किया जा सकता है (C# using, Java try-with-resources, Python with); नीचे देखें।

वैकल्पिक, अधिक अनिवार्य दृष्टिकोण, प्रत्यक्ष शैली में एसिंक्रोनस कोड लिखना है: एक संसाधन प्राप्त करें, और फिर अगली पंक्ति में एक स्थगित रिलीज है, जिसे स्कोप से बाहर निकलने पर कहा जाता है - एसिंक्रोनस रिलीज के बाद सिंक्रोनस अधिग्रहण। इसकी उत्पत्ति 2000 में आंद्रेई अलेक्जेंड्रेस्कु और पेट्रु मार्जिनियन द्वारा स्कोपगार्ड क्लास के रूप में हुई, [4] जोशुआ लेहरर द्वारा सुधार के साथ, [5] और scope कीवर्ड (स्कोपगार्डस्टेटमेंट) के माध्यम से डी में प्रत्यक्ष भाषा समर्थन है, जहां यह एक दृष्टिकोण है अपवाद सुरक्षा के लिए, RAII के अलावा (नीचे देखें)।[6] इसे गो (Go) में defer स्टेटमेंट के रूप में भी सम्मिलित किया गया है। [7] इस दृष्टिकोण में इनकैप्सुलेशन का अभाव है - किसी को स्पष्ट रूप से अधिग्रहण और रिलीज़ से मेल खाना चाहिए - लेकिन प्रत्येक संसाधन के लिए एक वस्तु बनाने से बचा जाता है (कोड-वार, प्रत्येक प्रकार के संसाधन के लिए एक वर्ग लिखने से बचें)।

वस्तु-उन्मुख प्रोग्रामिंग

वस्तु उन्मुख कार्यकर्म में, संसाधनों को उन वस्तुओं में समाहित किया जाता है जो उनका उपयोग करते हैं, जैसे कि a file फ़ील्ड (कंप्यूटर साइंस) वाली वस्तु जिसका मान फाइल डिस्क्रिप्टर (या अधिक सामान्य फ़ाइल संभाल) है। यह ऑब्जेक्ट के उपयोगकर्ताओं को ऐसा करने की आवश्यकता के बिना संसाधन का उपयोग और प्रबंधन करने की अनुमति देता है। हालाँकि, ऐसे कई तरीके हैं जिनसे वस्तुओं और संसाधनों को जोड़ा जा सकता है।

सबसे पहले, स्वामित्व का प्रश्न है: क्या किसी वस्तु के पास संसाधन है?

  • वस्तुएं संसाधनों का मालिक हो सकती हैं (वस्तु संरचना के माध्यम से, एक मजबूत संबंध है)।
  • ऑब्जेक्ट संसाधन देख सकते हैं (ऑब्जेक्ट एकत्रीकरण के माध्यम से, एक कमजोर संबंध है)।
  • ऑब्जेक्ट अन्य ऑब्जेक्ट्स के साथ संवाद कर सकते हैं जिनके पास संसाधन हैं (एसोसिएशन (ऑब्जेक्ट-ओरिएंटेड प्रोग्रामिंग) के माध्यम से)।

जिन वस्तुओं के पास संसाधन है, वे वस्तु जीवनकाल के दौरान अलग-अलग बिंदुओं पर इसे अलग-अलग तरीकों से प्राप्त और जारी कर सकते हैं; ये जोड़े में होते हैं, लेकिन व्यवहार में इन्हें अक्सर सममित रूप से उपयोग नहीं किया जाता है (नीचे देखें):

  • (उदाहरण) विधियों जैसे कि वस्तु के वैध होने के दौरान प्राप्त / जारी करें open या dispose.
  • ऑब्जेक्ट निर्माण/विनाश (इनिशियलाइज़र और फ़ाइनलाइज़र में) के दौरान अधिग्रहण/रिलीज़ करें।
  • न तो संसाधन प्राप्त करें और न ही जारी करें, इसके बजाय केवल एक संसाधन के लिए एक दृश्य या संदर्भ वस्तु के लिए बाहरी रूप से प्रबंधित किया जाता है, जैसा कि निर्भरता इंजेक्शन में होता है; संक्षेप में, एक ऑब्जेक्ट जिसमें संसाधन है (या जो करता है उसके साथ संवाद कर सकता है) एक विधि या कन्स्ट्रक्टर के तर्क के रूप में पारित किया जाता है।

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

राय

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

RAII C++ में मानक संसाधन प्रबंधन दृष्टिकोण है, लेकिन इसकी अपील के बावजूद, C++ के बाहर बहुत कम उपयोग किया जाता है, क्योंकि यह आधुनिक स्वचालित मेमोरी प्रबंधन के साथ खराब तरीके से काम करता है, विशेष रूप से कचरा संग्रह का पता लगाना: RAII संसाधन प्रबंधन को स्मृति प्रबंधन से जोड़ता है, लेकिन इनमें महत्वपूर्ण अंतर हैं . सबसे पहले, क्योंकि संसाधन महंगे हैं, उन्हें तुरंत जारी करना वांछनीय है, इसलिए संसाधनों को रखने वाली वस्तुओं को जल्द से जल्द नष्ट कर दिया जाना चाहिए (वे अब उपयोग में नहीं हैं)। नियतात्मक स्मृति प्रबंधन में वस्तु का विनाश शीघ्र होता है, जैसे कि C++ में (स्टैक-आवंटित वस्तुओं को ढेर खोलने पर नष्ट कर दिया जाता है, हीप-आवंटित वस्तुओं को कॉल करके मैन्युअल रूप से नष्ट कर दिया जाता है delete या स्वचालित रूप से उपयोग करना unique_ptr) या नियतात्मक संदर्भ-गणना में (जहां वस्तुओं को तुरंत नष्ट कर दिया जाता है जब उनकी संदर्भ संख्या 0 तक गिर जाती है), और इस प्रकार RAII इन स्थितियों में अच्छा काम करता है। हालाँकि, अधिकांश आधुनिक स्वचालित मेमोरी प्रबंधन गैर-नियतात्मक है, इस बात की कोई गारंटी नहीं है कि वस्तुओं को तुरंत या बिल्कुल भी नष्ट कर दिया जाएगा! ऐसा इसलिए है क्योंकि कचरा बनने पर प्रत्येक वस्तु को तुरंत ठीक से इकट्ठा करने की तुलना में आवंटित कुछ कचरा छोड़ना सस्ता है। दूसरे, वस्तु के विनाश के दौरान संसाधनों को जारी करने का अर्थ है कि एक वस्तु के पास अंतिम रूप होना चाहिए (नियतात्मक स्मृति प्रबंधन में एक विनाशक के रूप में जाना जाता है) - वस्तु को आसानी से हटाया नहीं जा सकता है - जो कचरा संग्रह को काफी सम्मिश्र और धीमा कर देता है।

सम्मिश्र सम्बन्ध

जब कई वस्तुएं एक ही संसाधन पर निर्भर करती हैं, तो संसाधन प्रबंधन सम्मिश्र हो सकता है।

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

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

कार्यान्वयन-वार, ऑब्जेक्ट संरचना में, यदि डिस्पोजल पैटर्न का उपयोग किया जाता है, तो स्वामित्व वाली वस्तु में भी a होगा dispose विधि, जो बदले में कॉल करती है dispose स्वामित्व वाली वस्तुओं के तरीके जिनका निपटान किया जाना चाहिए; आरएआईआई में इसे स्वचालित रूप से संभाला जाता है (जब तक स्वामित्व वाली वस्तुएं स्वचालित रूप से नष्ट हो जाती हैं: सी ++ में यदि वे मूल्य या ए हैं unique_ptr, लेकिन कच्चा सूचक नहीं: सूचक स्वामित्व देखें)। वस्तु एकत्रीकरण में, देखने वाली वस्तु द्वारा कुछ भी करने की आवश्यकता नहीं है, क्योंकि यह संसाधन के लिए ज़िम्मेदार नहीं है।

दोनों सामान्यतौर पर पाए जाते हैं। उदाहरण के लिए, जावा क्लास लाइब्रेरी में, Reader#close() अंतर्निहित धारा को बंद कर देता है, और इन्हें जंजीर से बांधा जा सकता है। उदाहरण के लिए, ए BufferedReader एक सम्मिलित हो सकता है InputStreamReader, जिसमें बदले में एक सम्मिलित है FileInputStream, और बुला रहा है close पर BufferedReader बदले में बंद कर देता है InputStreamReader, जो बदले में बंद कर देता है FileInputStream, जो बदले में सिस्टम फ़ाइल संसाधन को रिलीज़ करता है। वास्तव में, संसाधन का सीधे उपयोग करने वाली वस्तु गुमनाम भी हो सकती है, एनकैप्सुलेशन के लिए धन्यवाद:

try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(fileName)))) {
    // Use reader.
}
// reader is closed when the try-with-resources block is exited, which closes each of the contained objects in sequence.


हालाँकि, केवल उस वस्तु का प्रबंधन करना भी संभव है जो सीधे संसाधन का उपयोग करती है, और आवरण वस्तुओं पर संसाधन प्रबंधन का उपयोग नहीं करती है:

try (FileInputStream stream = new FileInputStream(fileName)))) {
    BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
    // Use reader.
}
// stream is closed when the try-with-resources block is exited.
// reader is no longer usable after stream is closed, but so long as it does not escape the block, this is not a problem.

इसके विपरीत, पायथन में, एक csv.reader उस file का स्वामी नहीं है जिसे वह पढ़ रहा है, इसलिए पाठक को बंद करने की कोई आवश्यकता नहीं है (और यह संभव नहीं है), और इसके बजाय file को स्वयं बंद होना चाहिए। [8]

with open(filename) as f:
    r = csv.reader(f)
    # Use r.
# f is closed when the with-statement is exited, and can no longer be used.
# Nothing is done to r, but the underlying f is closed, so r cannot be used either.

In. NET में, सम्मेलन केवल संसाधनों के प्रत्यक्ष उपयोगकर्ता के लिए ज़िम्मेदार है: "आपको आईडीस्पोजेबल केवल तभी लागू करना चाहिए जब आपका प्रकार अप्रबंधित संसाधनों का सीधे उपयोग करता है।"[9]

अधिक जटिल ऑब्जेक्ट ग्राफ़ के मामले में, जैसे संसाधनों को साझा करने वाली कई ऑब्जेक्ट, या संसाधनों को धारण करने वाली वस्तुओं के बीच चक्र, उचित संसाधन प्रबंधन काफी जटिल हो सकता है, और वास्तव में वही समस्याएँ उत्पन्न होती हैं जो ऑब्जेक्ट फ़ाइनलाइज़ेशन (विनाशकों या फ़ाइनलाइज़र के माध्यम से) में उत्पन्न होती हैं; उदाहरण के लिए, व्यपगत श्रोता समस्या हो सकती है और पर्यवेक्षक पैटर्न (और पर्यवेक्षक संसाधनों को धारण करते हैं) का उपयोग करते हुए संसाधन रिसाव का कारण बन सकते हैं। संसाधन प्रबंधन के अधिक नियंत्रण की अनुमति देने के लिए विभिन्न तंत्र मौजूद हैं। उदाहरण के लिए, Google क्लोजर लाइब्रेरी में, goog. Disposable क्लास इस ऑब्जेक्ट के साथ निपटाने के लिए अन्य ऑब्जेक्ट्स को पंजीकृत करने के लिए एक registerDisposable विधि प्रदान करता है, साथ ही निपटान के प्रबंधन के लिए विभिन्न निम्न-स्तरीय उदाहरण और क्लास विधियों के साथ।

संरचित प्रोग्रामिंग

संरचित प्रोग्रामिंग में, सभी मामलों को संभालने के लिए पर्याप्त रूप से नेस्टिंग कोड द्वारा स्टैक संसाधन प्रबंधन किया जाता है। इसके लिए कोड के अंत में केवल एक वापसी की आवश्यकता होती है, और यदि बहुत सारे संसाधनों को प्राप्त किया जाना चाहिए, तो भारी नेस्टेड कोड हो सकता है, जिसे कुछ लोगों द्वारा एक विरोधी पैटर्न माना जाता है - एरोएंटीपैटर्न एरो एंटीपैटर्न,[10] क्रमिक नेस्टिंग से त्रिकोणीय आकार के कारण।

क्लीनअप क्लॉज़

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

यह भी देखें

संदर्भ

  1. 1.0 1.1 Beck 1997, pp. 37–39.
  2. 2.0 2.1 Elder, Jackson & Liblit 2008, p. 3.
  3. Elder, Jackson & Liblit 2008, p. 2.
  4. "Generic: Change the Way You Write Exception-Safe Code — Forever", by Andrei Alexandrescu and Petru Marginean, December 01, 2000, Dr. Dobb's
  5. ScopeGuard 2.0, Joshua Lehrer
  6. D: Exception Safety
  7. Defer, Panic, and Recover, Andrew Gerrand, The Go Blog, 4 August 2010
  8. Python: No csv.close()?
  9. "IDisposable Interface". Retrieved 2016-04-03.
  10. Flattening Arrow Code, Jeff Atwood, 10 Jan 2006


अग्रिम पठन

बाहरी संबंध