संसाधन प्रबंधन (कंप्यूटिंग): Difference between revisions
No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
[[कंप्यूटर प्रोग्रामिंग]] में, '''संसाधन प्रबंधन''' [[सिस्टम संसाधन]] (सीमित उपलब्धता वाले घटक) के प्रबंधन के लिए तकनीकों को संदर्भित करता है। | [[कंप्यूटर प्रोग्रामिंग]] में, '''संसाधन प्रबंधन''' [[सिस्टम संसाधन]] (सीमित उपलब्धता वाले घटक) के प्रबंधन के लिए तकनीकों को संदर्भित करता है। | ||
[[:hi:कम्प्यूटर प्रोग्राम|कंप्यूटर प्रोग्राम]] अपने स्वयं के संसाधनों का प्रबंधन कर सकते हैं [[:hi:प्रोग्रामिंग भाषा|प्रोग्रामिंग लैंग्वेज]] | [[:hi:कम्प्यूटर प्रोग्राम|कंप्यूटर प्रोग्राम]] अपने स्वयं के संसाधनों का प्रबंधन कर सकते हैं [[:hi:प्रोग्रामिंग भाषा|प्रोग्रामिंग लैंग्वेज]] विभिन्न दृष्टिकोणों के विपरीत एक सर्वेक्षण लेख है) द्वारा प्रदर्शित सुविधाओं का उपयोग करके, या उन्हें एक होस्ट - एक [[:hi:प्रचालन तन्त्र|ऑपरेटिंग सिस्टम]] या [[:hi:आभासी मशीन|वर्चुअल मशीन]] - या किसी अन्य प्रोग्राम द्वारा प्रबंधित करने का चुनाव कर सकता है। | ||
होस्ट-आधारित प्रबंधन को ''संसाधन ट्रैकिंग के रूप में जाना जाता है,'' और इसमें संसाधनों के रिसाव को साफ करना शामिल है: संसाधनों तक पहुंच को समाप्त करना जो कि अधिग्रहित किए गए हैं लेकिन उपयोग के बाद जारी नहीं किए गए हैं। इसे ''रिक्लेमिंग'' रिसोर्सेज के रूप में जाना जाता है, और मेमोरी के लिए [[:hi:कचरा संग्रह (कंप्यूटर विज्ञान)| | होस्ट-आधारित प्रबंधन को ''संसाधन ट्रैकिंग के रूप में जाना जाता है,'' और इसमें संसाधनों के रिसाव को साफ करना शामिल है: संसाधनों तक पहुंच को समाप्त करना जो कि अधिग्रहित किए गए हैं लेकिन उपयोग के बाद जारी नहीं किए गए हैं। इसे ''रिक्लेमिंग'' रिसोर्सेज के रूप में जाना जाता है, और मेमोरी के लिए [[:hi:कचरा संग्रह (कंप्यूटर विज्ञान)|अपशिष्ट संग्रहण]] (गार्बेज कलेक्शन ) के समान है। कई प्रणालियों पर, प्रक्रिया के बाहर निकलने के बाद ऑपरेटिंग [[:hi:सिस्टम कॉल|सिस्टम]] संसाधनों को पुनः प्राप्त करता है। | ||
== | == नियंत्रक अभिगम == | ||
जब किसी प्रोग्राम का उपयोग समाप्त हो जाता है तो संसाधन को जारी करने की चूक को [[संसाधन रिसाव]] के रूप में जाना जाता है, और अनुक्रमिक कंप्यूटिंग में एक समस्या है। एक सीमित संसाधन तक पहुँचने | जब किसी प्रोग्राम का उपयोग करना समाप्त हो जाता है तो संसाधन को जारी करने की चूक को [[संसाधन रिसाव|संसाधन क्षरण]] (रिसोर्स लीक) के रूप में जाना जाता है, और अनुक्रमिक कंप्यूटिंग में एक समस्या है। एक सीमित संसाधन तक पहुँचने के लिए कई प्रक्रियाएँ [[समवर्ती कंप्यूटिंग]] में एक समस्या हो सकती हैं, और इसे संसाधन विवाद के रूप में जाना जाता है। | ||
संसाधन प्रबंधन इन दोनों स्थितियों को रोकने के लिए | संसाधन प्रबंधन इन दोनों स्थितियों को रोकने के लिए अभिगम को नियंत्रित करने का प्रयास करता है। | ||
=== | === रिसोर्स लीक === | ||
{{main| | {{main|रिसोर्स लीक}} | ||
औपचारिक रूप से, संसाधन प्रबंधन (संसाधन रिसाव को रोकना) में यह सुनिश्चित करना शामिल है कि एक संसाधन तभी जारी किया जाता है जब उसे सफलतापूर्वक अधिग्रहित किया जाता है। इस सामान्य समस्या को " ''पहले,'' ''बॉडी,'' और ''बाद में'' " कोड के रूप में समझा जा सकता है, जो आम तौर पर इस क्रम में निष्पादित होते हैं, इस शर्त के साथ कि ''बाद'' के कोड को केवल तभी कहा जाता है जब ''पहले'' कोड सफलतापूर्वक पूरा हो जाता है, भले ही ''बॉडी'' कोड सफलतापूर्वक क्रियान्वित होता है या नहीं। इसे{{Sfn|Beck|1997|pp=37–39}} या एक ''कोड सैंडविच के'' ''आसपास निष्पादित'' के रूप में भी जाना जाता है, और विभिन्न अन्य संदर्भों में होता है,{{Sfn|Elder|Jackson|Liblit|2008|p=3}} जैसे कि कार्यक्रम की स्थिति का एक अस्थायी परिवर्तन, या एक [[सबरूटीन]] में प्रवेश और निकास का पता लगाना है। हालाँकि, संसाधन प्रबंधन सबसे अधिक उद्धृत अनुप्रयोग है। आस्पेक्ट-ओरिएंटेड प्रोग्रामिंग में, लॉजिक के चारों ओर ऐसा निष्पादन सूचना का एक रूप है। | |||
[[:hi:नियंत्रण प्रवाह विश्लेषण|नियंत्रण प्रवाह विश्लेषण]] की शब्दावली में, संसाधन रिलीज को सफल संसाधन अधिग्रहण पर हावी होना चाहिए; {{Sfn|Elder|Jackson|Liblit|2008|p=2}} यह सुनिश्चित करने में विफलता कि यह एक बग है, और एक कोड पथ जो इस शर्त का उल्लंघन करता है, संसाधन रिसाव का कारण बनता है। संसाधन रिसाव अक्सर छोटी समस्याएं होती हैं, आम तौर पर कार्यक्रम को क्रैश नहीं करती हैं, बल्कि इसके बजाय कार्यक्रम या समग्र प्रणाली को कुछ धीमा कर देती हैं।{{Sfn|Elder|Jackson|Liblit|2008|p=3}} हालांकि, वे क्रैश का कारण बन सकते हैं - या तो प्रोग्राम या अन्य प्रोग्राम - ''संसाधन थकावट के कारण:'' यदि सिस्टम संसाधनों से बाहर हो जाता है, तो अधिग्रहण अनुरोध विफल हो जाते हैं। यह एक सुरक्षा बग (सिक्योरिटी बग)पे श कर सकता है यदि कोई हमला संसाधन थकावट का कारण बन सकता है। संसाधन रिसाव नियमित कार्यक्रम प्रवाह के तहत हो सकता है - जैसे कि संसाधन को जारी करना भूल जाना - या केवल असाधारण परिस्थितियों में, जैसे कि जब कार्यक्रम के दूसरे भाग में कोई अपवाद हो तो संसाधन जारी नहीं किया जाता है। रिसोर्स लीक बहुत बार एक सबरूटीन से जल्दी बाहर निकलने के कारण होता है, या तो <code>return</code> स्टेटमेंट द्वारा, या सबरूटीन द्वारा उठाया गया अपवाद, या एक गहरा सबरूटीन जिसे वह कॉल करता है। जबकि रिटर्न स्टेटमेंट के कारण रिसोर्स रिलीज को रिटर्न से पहले सबरूटीन के भीतर सावधानी से रिलीज करके संभाला जा सकता है, कुछ अतिरिक्त भाषा सुविधा के बिना अपवादों को हैंडल नहीं किया जा सकता है जो गारंटी देता है कि रिलीज कोड निष्पादित किया गया है। | |||
अधिक संक्षेप में, सफल संसाधन अधिग्रहण संसाधन रिलीज पर हावी होना चाहिए, अन्यथा कोड उस संसाधन को जारी करने का प्रयास करेगा जिसे उसने अधिग्रहित नहीं किया है। इस तरह के एक गलत रिलीज के परिणाम चुपचाप अनदेखा किए जाने से लेकर प्रोग्राम को क्रैश करने या अप्रत्याशित व्यवहार तक हो सकते हैं। ये बग आम तौर पर शायद ही कभी प्रकट होते हैं, क्योंकि उन्हें पहले विफल होने के लिए संसाधन आवंटन की आवश्यकता होती है, जो आम तौर पर एक असाधारण मामला है। इसके अलावा, परिणाम गंभीर नहीं हो सकते हैं, क्योंकि एक आवश्यक संसाधन प्राप्त करने में विफलता के कारण प्रोग्राम पहले से ही क्रैश हो सकता है। हालाँकि, ये विफलता से पुनर्प्राप्ति को रोक सकते हैं, या एक व्यवस्थित शटडाउन को अव्यवस्थित शटडाउन में बदल सकते हैं। इस स्थिति को आम तौर पर पहले जाँच कर सुनिश्चित किया जाता है कि संसाधन को सफलतापूर्वक प्राप्त करने से पहले इसे जारी किया गया था, या तो "सफलतापूर्वक अधिग्रहित" रिकॉर्ड करने के लिए एक बूलियन चर होने से - जिसमें संसाधन का अधिग्रहण होने पर परमाणुता का अभाव है, लेकिन ध्वज चर को अद्यतन करने में विफल रहता है, या इसके विपरीत - या संसाधन के हैंडल द्वारा एक अशक्त प्रकार होने के नाते, जहां "शून्य" "सफलतापूर्वक अधिग्रहित नहीं" इंगित करता है, जो परमाणुता सुनिश्चित करता है। | |||
{{ | == मेमोरी मैनेजमेंट == | ||
{{main|मेमोरी प्रबंधन}} | |||
मेमोरी को एक संसाधन के रूप में माना जा सकता है, लेकिन [[मेमोरी प्रबंधन इकाई|मेमोरी प्रबंधन]] को आमतौर पर अलग से माना जाता है, मुख्यतः क्योंकि स्मृति आवंटन और डीलोकेशन फ़ाइल हैंडल जैसे अन्य संसाधनों के अधिग्रहण और रिलीज की तुलना में काफी अधिक होता है। ''बाहरी'' सिस्टम द्वारा प्रबंधित मेमोरी में (आंतरिक) मेमोरी प्रबंधन (चूंकि यह मेमोरी है) और संसाधन प्रबंधन (चूंकि यह बाहरी सिस्टम द्वारा प्रबंधित किया जाता है) दोनों में समानता है। उदाहरणों में नेटिव कोड के माध्यम से प्रबंधित और जावा से उपयोग की जाने वाली मेमोरी शामिल है ( जावा नेटिव इंटरफ़ेस के माध्यम से); और [[:hi:जावास्क्रिप्ट|जावास्क्रिप्ट]] से उपयोग किए गए दस्तावेज़ ऑब्जेक्ट मॉडल (डीओएम) में ऑब्जेक्ट। इन दोनों मामलों में, रनटाइम वातावरण (वर्चुअल मशीन) का [[:hi:स्मृति प्रबंधन|मेमोरी मैनेजर]] ([[:hi:कचरा संग्रह (कंप्यूटर विज्ञान)|गारबेज कलेक्टर]]) बाहरी मेमोरी को प्रबंधित करने में असमर्थ है (कोई साझा मेमोरी प्रबंधन नहीं है), और इस प्रकार बाहरी मेमोरी को एक संसाधन के रूप में माना जाता है, और समान रूप से प्रबंधित किया जाता है। . हालाँकि, सिस्टम के बीच चक्र (जावास्क्रिप्ट DOM का संदर्भ देता है, जावास्क्रिप्ट का संदर्भ देता है) प्रबंधन को कठिन या असंभव बना सकता है। | |||
मेमोरी को एक संसाधन के रूप में माना जा सकता है, लेकिन मेमोरी प्रबंधन को आमतौर पर अलग से माना जाता है, मुख्यतः क्योंकि स्मृति आवंटन और डीलोकेशन फ़ाइल हैंडल जैसे अन्य संसाधनों के अधिग्रहण और रिलीज की तुलना में काफी अधिक होता है। बाहरी सिस्टम द्वारा प्रबंधित | |||
== शाब्दिक प्रबंधन और स्पष्ट प्रबंधन == | == शाब्दिक प्रबंधन और स्पष्ट प्रबंधन == | ||
प्रोग्राम के भीतर संसाधन प्रबंधन में एक महत्वपूर्ण अंतर लेक्सिकल प्रबंधन और स्पष्ट प्रबंधन के बीच है - क्या एक संसाधन को लेक्सिकल स्कोप के रूप में संभाला जा सकता है, जैसे स्टैक वेरिएबल (लाइफटाइम एक सिंगल लेक्सिकल स्कोप तक सीमित है, प्रवेश पर प्राप्त किया जा रहा है या एक विशेष दायरे के भीतर, और तब जारी किया जाता है जब निष्पादन उस दायरे से बाहर हो जाता है), या क्या एक संसाधन को स्पष्ट रूप से आवंटित और जारी किया जाना चाहिए, जैसे कि किसी फ़ंक्शन के भीतर प्राप्त किया गया संसाधन और फिर उससे वापस आ गया, जिसे अधिग्रहण फ़ंक्शन के बाहर जारी किया जाना चाहिए। लेक्सिकल प्रबंधन, जब लागू हो, चिंताओं को बेहतर ढंग से अलग करने की अनुमति देता है और कम त्रुटि-प्रवण है। | |||
== | == मूलभूत तकनीकें == | ||
संसाधन प्रबंधन के लिए मूल दृष्टिकोण एक संसाधन प्राप्त करना है, इसके साथ कुछ करना है, फिर इसे जारी करना है, फॉर्म का कोड देना (पायथन में फ़ाइल खोलने के साथ सचित्र): | संसाधन प्रबंधन के लिए मूल दृष्टिकोण एक संसाधन प्राप्त करना है, इसके साथ कुछ करना है, फिर इसे जारी करना है, फॉर्म का कोड देना (पायथन में फ़ाइल खोलने के साथ सचित्र):<syntaxhighlight lang="python"> | ||
< | f = open(filename) | ||
... | ... | ||
f.close() | |||
</ | </syntaxhighlight>यह सही है अगर हस्तक्षेप करने वाले <code>...</code> कोड में प्रारंभिक निकास ( <code>return</code> ) नहीं है, भाषा में अपवाद नहीं <code>open</code>, और सफल होने की गारंटी है। हालाँकि, यदि रिटर्न या अपवाद होता है, तो यह संसाधन रिसाव का कारण बनता है, और यदि <code>open</code> विफल हो सकता है, तो अप्राप्त संसाधन की गलत रिलीज़ का कारण बनता है। | ||
यह सही है अगर हस्तक्षेप <code>...</code> कोड में | |||
यह सही है अगर हस्तक्षेप करने वाले <code>...</code> कोड में प्रारंभिक निकास (<code>return</code>) नहीं है, भाषा में अपवाद नहीं <code>open</code>, और सफल होने की गारंटी है। हालाँकि, यदि रिटर्न या अपवाद होता है, तो यह संसाधन रिसाव का कारण बनता है, और यदि <code>open</code> विफल हो सकता है, तो अप्राप्त संसाधन की गलत रिलीज़ का कारण बनता है। | |||
दो और मूलभूत समस्याएं हैं: अधिग्रहण-रिलीज़ जोड़ी आसन्न नहीं है (रिलीज़ कोड को अधिग्रहण कोड से दूर लिखा जाना चाहिए), और संसाधन प्रबंधन एनकैप्सुलेटेड नहीं है - प्रोग्रामर को मैन्युअल रूप से यह सुनिश्चित करना चाहिए कि वे हमेशा जोड़े जाते हैं। संयोजन में, इनका मतलब है कि अधिग्रहण और रिलीज को स्पष्ट रूप से जोड़ा जाना चाहिए, लेकिन एक साथ नहीं रखा जा सकता है, इस प्रकार इन्हें सही ढंग से जोड़ा नहीं जाना आसान हो जाता है।<syntaxhighlight lang="python"> | |||
f = open(filename) | |||
try: | |||
... | ... | ||
finally: | |||
f.close() | |||
</ | </syntaxhighlight> | ||
यह सही रिलीज सुनिश्चित करता है, भले ही शरीर के भीतर वापसी हो या कोई अपवाद फेंका गया हो। इसके अलावा, ध्यान दें कि अधिग्रहण | |||
< | |||
यह सही रिलीज सुनिश्चित करता है, भले ही शरीर के भीतर वापसी हो या कोई अपवाद फेंका गया हो। इसके अलावा, ध्यान दें कि अधिग्रहण <code>try</code> खंड ''से पहले'' होता है, यह सुनिश्चित करते हुए कि <code>finally</code> खंड केवल तभी निष्पादित होता है जब <code>open</code> कोड सफल होता है (बिना किसी अपवाद को फेंके), यह मानते हुए कि "कोई अपवाद नहीं" का अर्थ "सफलता" है (जैसा कि <code>open</code> में मामला है) पायथन)। यदि संसाधन अधिग्रहण बिना किसी अपवाद के विफल हो सकता है, जैसे कि <code>null</code> का एक रूप लौटाकर, इसे रिलीज से पहले भी जांचा जाना चाहिए, जैसे:<syntaxhighlight lang="python"> | |||
f = open(filename) | |||
try: | |||
... | ... | ||
finally: | |||
if f: | |||
f.close() | |||
</ | </syntaxhighlight>जबकि यह सही संसाधन प्रबंधन सुनिश्चित करता है, यह निकटता या एनकैप्सुलेशन प्रदान करने में विफल रहता है। कई भाषाओं में ऐसे तंत्र हैं जो इनकैप्सुलेशन प्रदान करते हैं, जैसे कि पायथन में कथन के <code>with</code> :<syntaxhighlight lang="python"> | ||
जबकि यह सही संसाधन प्रबंधन सुनिश्चित करता है, यह निकटता या एनकैप्सुलेशन प्रदान करने में विफल रहता है। कई भाषाओं में ऐसे तंत्र हैं जो इनकैप्सुलेशन प्रदान करते हैं, जैसे कि <code>with</code> | with open(filename) as f: | ||
< | |||
... | ... | ||
</ | </syntaxhighlight>उपरोक्त तकनीकें - अनवाइंड प्रोटेक्शन ( <code>finally</code> ) और एनकैप्सुलेशन के कुछ रूप - संसाधन प्रबंधन के लिए सबसे आम दृष्टिकोण हैं, जो C#, [[कॉमन लिस्प]], जावा, पायथन, रूबी, [[स्कीम]] और स्मॉलटॉक, {{Sfn|Beck|1997|pp=37–39}} में विभिन्न रूपों में पाए जाते हैं। ; वे लिस्प की [[NIL]] बोली में 1970 के दशक के उत्तरार्ध में हैं; अपवाद प्रबंधन § इतिहास । कान्वयन में कई विविधताएँ हैं, और काफी भिन्न [[:hi:Resource_management_(computing)#Approaches|दृष्टिकोण]] भी हैं। | ||
... | |||
उपरोक्त तकनीकें - सुरक्षा खोलना (<code>finally</code>) और एनकैप्सुलेशन के कुछ रूप - संसाधन प्रबंधन के लिए सबसे आम दृष्टिकोण हैं, जो C#, [[सामान्य लिस्प]], जावा, पायथन, रूबी, स्कीम (प्रोग्रामिंग लैंग्वेज) और स्मॉलटॉक में विभिन्न रूपों में पाए जाते हैं।{{sfn|Beck|1997|pp=37–39}} दूसरों के बीच में; वे लिस्प की NIL (प्रोग्रामिंग भाषा) बोली में 1970 के दशक के उत्तरार्ध में हैं; देखना {{section link|Exception handling|History}}. कार्यान्वयन में कई विविधताएँ हैं, और काफी भिन्न #दृष्टिकोण भी हैं। | उपरोक्त तकनीकें - सुरक्षा खोलना (<code>finally</code>) और एनकैप्सुलेशन के कुछ रूप - संसाधन प्रबंधन के लिए सबसे आम दृष्टिकोण हैं, जो C#, [[सामान्य लिस्प]], जावा, पायथन, रूबी, स्कीम (प्रोग्रामिंग लैंग्वेज) और स्मॉलटॉक में विभिन्न रूपों में पाए जाते हैं।{{sfn|Beck|1997|pp=37–39}} दूसरों के बीच में; वे लिस्प की NIL (प्रोग्रामिंग भाषा) बोली में 1970 के दशक के उत्तरार्ध में हैं; देखना {{section link|Exception handling|History}}. कार्यान्वयन में कई विविधताएँ हैं, और काफी भिन्न #दृष्टिकोण भी हैं। | ||
Line 71: | Line 67: | ||
== दृष्टिकोण == | == दृष्टिकोण == | ||
=== | === उनविंड सुरक्षा === | ||
सभी भाषाओं में संसाधन प्रबंधन के लिए सबसे आम दृष्टिकोण सुरक्षा का उपयोग करना है, जिसे तब कहा जाता है जब निष्पादन एक दायरे से बाहर निकलता है - ब्लॉक के अंत में निष्पादन द्वारा, ब्लॉक के भीतर से वापस आने पर, या एक अपवाद फेंके जाने पर। यह स्टैक-प्रबंधित संसाधनों के लिए काम करता है, और C#, कॉमन लिस्प, जावा, पायथन, रूबी और स्कीम सहित कई भाषाओं में लागू किया गया है। इस दृष्टिकोण के साथ मुख्य समस्या यह है कि रिलीज़ कोड (आमतौर पर a <code>finally</code> क्लॉज) अधिग्रहण कोड से बहुत दूर हो सकता है (इसमें निकटता की कमी है), और यह कि अधिग्रहण और रिलीज़ कोड को हमेशा कॉलर द्वारा जोड़ा जाना चाहिए (इसमें एनकैप्सुलेशन की कमी है)। क्लोजर/कॉलबैक/कोरटाइन (कॉमन लिस्प, रूबी, स्कीम) का उपयोग करके या अधिग्रहण और रिलीज दोनों को संभालने वाली वस्तु का उपयोग करके और नियंत्रण में प्रवेश करने और बाहर निकलने पर इन विधियों को कॉल करने के लिए एक भाषा निर्माण को जोड़कर या तो कार्यात्मक रूप से इनका उपचार किया जा सकता है। एक दायरा (सी# <code>using</code>, जावा <code>try</code>-संसाधनों के साथ, पायथन <code>with</code>); नीचे देखें। | '''सभी''' भाषाओं में संसाधन प्रबंधन के लिए सबसे आम दृष्टिकोण सुरक्षा का उपयोग करना है, जिसे तब कहा जाता है जब निष्पादन एक दायरे से बाहर निकलता है - ब्लॉक के अंत में निष्पादन द्वारा, ब्लॉक के भीतर से वापस आने पर, या एक अपवाद फेंके जाने पर। यह स्टैक-प्रबंधित संसाधनों के लिए काम करता है, और C#, कॉमन लिस्प, जावा, पायथन, रूबी और स्कीम सहित कई भाषाओं में लागू किया गया है। इस दृष्टिकोण के साथ मुख्य समस्या यह है कि रिलीज़ कोड (आमतौर पर a <code>finally</code> क्लॉज) अधिग्रहण कोड से बहुत दूर हो सकता है (इसमें निकटता की कमी है), और यह कि अधिग्रहण और रिलीज़ कोड को हमेशा कॉलर द्वारा जोड़ा जाना चाहिए (इसमें एनकैप्सुलेशन की कमी है)। क्लोजर/कॉलबैक/कोरटाइन (कॉमन लिस्प, रूबी, स्कीम) का उपयोग करके या अधिग्रहण और रिलीज दोनों को संभालने वाली वस्तु का उपयोग करके और नियंत्रण में प्रवेश करने और बाहर निकलने पर इन विधियों को कॉल करने के लिए एक भाषा निर्माण को जोड़कर या तो कार्यात्मक रूप से इनका उपचार किया जा सकता है। एक दायरा (सी# <code>using</code>, जावा <code>try</code>-संसाधनों के साथ, पायथन <code>with</code>); नीचे देखें। | ||
एक वैकल्पिक, अधिक अनिवार्य दृष्टिकोण, एसिंक्रोनस कोड को सीधे शैली में लिखना है: एक संसाधन प्राप्त करें, और फिर अगली पंक्ति में एक आस्थगित रिलीज़ हो, जिसे स्कोप से बाहर निकलने पर कहा जाता है - सिंक्रोनस अधिग्रहण के बाद एसिंक्रोनस रिलीज़। इसकी उत्पत्ति 2000 में [[आंद्रेई अलेक्जेंड्रेस्कु]] और पेट्रु मार्जिनियन द्वारा स्कोपगार्ड क्लास के रूप में सी ++ में हुई थी। | एक वैकल्पिक, अधिक अनिवार्य दृष्टिकोण, एसिंक्रोनस कोड को सीधे शैली में लिखना है: एक संसाधन प्राप्त करें, और फिर अगली पंक्ति में एक आस्थगित रिलीज़ हो, जिसे स्कोप से बाहर निकलने पर कहा जाता है - सिंक्रोनस अधिग्रहण के बाद एसिंक्रोनस रिलीज़। इसकी उत्पत्ति 2000 में [[आंद्रेई अलेक्जेंड्रेस्कु]] और पेट्रु मार्जिनियन द्वारा स्कोपगार्ड क्लास के रूप में सी ++ में हुई थी। |
Revision as of 00:37, 20 December 2022
कंप्यूटर प्रोग्रामिंग में, संसाधन प्रबंधन सिस्टम संसाधन (सीमित उपलब्धता वाले घटक) के प्रबंधन के लिए तकनीकों को संदर्भित करता है।
कंप्यूटर प्रोग्राम अपने स्वयं के संसाधनों का प्रबंधन कर सकते हैं प्रोग्रामिंग लैंग्वेज विभिन्न दृष्टिकोणों के विपरीत एक सर्वेक्षण लेख है) द्वारा प्रदर्शित सुविधाओं का उपयोग करके, या उन्हें एक होस्ट - एक ऑपरेटिंग सिस्टम या वर्चुअल मशीन - या किसी अन्य प्रोग्राम द्वारा प्रबंधित करने का चुनाव कर सकता है।
होस्ट-आधारित प्रबंधन को संसाधन ट्रैकिंग के रूप में जाना जाता है, और इसमें संसाधनों के रिसाव को साफ करना शामिल है: संसाधनों तक पहुंच को समाप्त करना जो कि अधिग्रहित किए गए हैं लेकिन उपयोग के बाद जारी नहीं किए गए हैं। इसे रिक्लेमिंग रिसोर्सेज के रूप में जाना जाता है, और मेमोरी के लिए अपशिष्ट संग्रहण (गार्बेज कलेक्शन ) के समान है। कई प्रणालियों पर, प्रक्रिया के बाहर निकलने के बाद ऑपरेटिंग सिस्टम संसाधनों को पुनः प्राप्त करता है।
नियंत्रक अभिगम
जब किसी प्रोग्राम का उपयोग करना समाप्त हो जाता है तो संसाधन को जारी करने की चूक को संसाधन क्षरण (रिसोर्स लीक) के रूप में जाना जाता है, और अनुक्रमिक कंप्यूटिंग में एक समस्या है। एक सीमित संसाधन तक पहुँचने के लिए कई प्रक्रियाएँ समवर्ती कंप्यूटिंग में एक समस्या हो सकती हैं, और इसे संसाधन विवाद के रूप में जाना जाता है।
संसाधन प्रबंधन इन दोनों स्थितियों को रोकने के लिए अभिगम को नियंत्रित करने का प्रयास करता है।
रिसोर्स लीक
औपचारिक रूप से, संसाधन प्रबंधन (संसाधन रिसाव को रोकना) में यह सुनिश्चित करना शामिल है कि एक संसाधन तभी जारी किया जाता है जब उसे सफलतापूर्वक अधिग्रहित किया जाता है। इस सामान्य समस्या को " पहले, बॉडी, और बाद में " कोड के रूप में समझा जा सकता है, जो आम तौर पर इस क्रम में निष्पादित होते हैं, इस शर्त के साथ कि बाद के कोड को केवल तभी कहा जाता है जब पहले कोड सफलतापूर्वक पूरा हो जाता है, भले ही बॉडी कोड सफलतापूर्वक क्रियान्वित होता है या नहीं। इसे[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 के दशक के उत्तरार्ध में हैं; अपवाद प्रबंधन § इतिहास । कान्वयन में कई विविधताएँ हैं, और काफी भिन्न दृष्टिकोण भी हैं।
...
उपरोक्त तकनीकें - सुरक्षा खोलना (finally
) और एनकैप्सुलेशन के कुछ रूप - संसाधन प्रबंधन के लिए सबसे आम दृष्टिकोण हैं, जो C#, सामान्य लिस्प, जावा, पायथन, रूबी, स्कीम (प्रोग्रामिंग लैंग्वेज) और स्मॉलटॉक में विभिन्न रूपों में पाए जाते हैं।[1] दूसरों के बीच में; वे लिस्प की NIL (प्रोग्रामिंग भाषा) बोली में 1970 के दशक के उत्तरार्ध में हैं; देखना Exception handling § History. कार्यान्वयन में कई विविधताएँ हैं, और काफी भिन्न #दृष्टिकोण भी हैं।
दृष्टिकोण
उनविंड सुरक्षा
सभी भाषाओं में संसाधन प्रबंधन के लिए सबसे आम दृष्टिकोण सुरक्षा का उपयोग करना है, जिसे तब कहा जाता है जब निष्पादन एक दायरे से बाहर निकलता है - ब्लॉक के अंत में निष्पादन द्वारा, ब्लॉक के भीतर से वापस आने पर, या एक अपवाद फेंके जाने पर। यह स्टैक-प्रबंधित संसाधनों के लिए काम करता है, और C#, कॉमन लिस्प, जावा, पायथन, रूबी और स्कीम सहित कई भाषाओं में लागू किया गया है। इस दृष्टिकोण के साथ मुख्य समस्या यह है कि रिलीज़ कोड (आमतौर पर a finally
क्लॉज) अधिग्रहण कोड से बहुत दूर हो सकता है (इसमें निकटता की कमी है), और यह कि अधिग्रहण और रिलीज़ कोड को हमेशा कॉलर द्वारा जोड़ा जाना चाहिए (इसमें एनकैप्सुलेशन की कमी है)। क्लोजर/कॉलबैक/कोरटाइन (कॉमन लिस्प, रूबी, स्कीम) का उपयोग करके या अधिग्रहण और रिलीज दोनों को संभालने वाली वस्तु का उपयोग करके और नियंत्रण में प्रवेश करने और बाहर निकलने पर इन विधियों को कॉल करने के लिए एक भाषा निर्माण को जोड़कर या तो कार्यात्मक रूप से इनका उपचार किया जा सकता है। एक दायरा (सी# using
, जावा try
-संसाधनों के साथ, पायथन with
); नीचे देखें।
एक वैकल्पिक, अधिक अनिवार्य दृष्टिकोण, एसिंक्रोनस कोड को सीधे शैली में लिखना है: एक संसाधन प्राप्त करें, और फिर अगली पंक्ति में एक आस्थगित रिलीज़ हो, जिसे स्कोप से बाहर निकलने पर कहा जाता है - सिंक्रोनस अधिग्रहण के बाद एसिंक्रोनस रिलीज़। इसकी उत्पत्ति 2000 में आंद्रेई अलेक्जेंड्रेस्कु और पेट्रु मार्जिनियन द्वारा स्कोपगार्ड क्लास के रूप में सी ++ में हुई थी।
[4] जोशुआ लेहरर द्वारा सुधार के साथ,[5] और डी के माध्यम से डी में प्रत्यक्ष भाषा समर्थन है scope
कीवर्ड (ScopeGuardStatement), जहां यह RAII के अलावा अपवाद सुरक्षा के लिए एक दृष्टिकोण है (नीचे देखें)।[6] इसे गो के रूप में भी शामिल किया गया है 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
, जो बदले में सिस्टम फ़ाइल संसाधन को रिलीज़ करता है। वास्तव में, संसाधन का सीधे उपयोग करने वाली वस्तु गुमनाम भी हो सकती है, एनकैप्सुलेशन के लिए धन्यवाद:
<वाक्यविन्यास प्रकाश लैंग = जावा> कोशिश करें (बफर्डरीडर रीडर = नया बफर्ड रीडर (नया इनपुटस्ट्रीम रीडर (नया फाइल इनपुटस्ट्रीम (फाइलनाम)))) {
// पाठक का प्रयोग करें।
} // पाठक बंद हो जाता है जब कोशिश-के-संसाधन ब्लॉक से बाहर निकलता है, जो अनुक्रम में निहित वस्तुओं में से प्रत्येक को बंद कर देता है। </वाक्यविन्यास हाइलाइट>
हालाँकि, केवल उस वस्तु का प्रबंधन करना भी संभव है जो सीधे संसाधन का उपयोग करती है, और आवरण वस्तुओं पर संसाधन प्रबंधन का उपयोग नहीं करती है: <वाक्यविन्यास प्रकाश लैंग = जावा> कोशिश करें (फाइलइनपुटस्ट्रीम स्ट्रीम = नया फाइलइनपुटस्ट्रीम (फाइलनाम))) {
BufferedReader रीडर = नया BufferedReader (नया InputStreamReader (स्ट्रीम)); // पाठक का प्रयोग करें।
} // स्ट्रीम बंद हो जाता है जब कोशिश-के-संसाधन ब्लॉक से बाहर निकल जाता है। // स्ट्रीम बंद होने के बाद पाठक अब उपयोग करने योग्य नहीं है, लेकिन जब तक यह ब्लॉक से बाहर नहीं निकलता है, यह कोई समस्या नहीं है। </वाक्यविन्यास हाइलाइट>
इसके विपरीत, पायथन में, एक csv.reader का स्वामी नहीं है file
यह पढ़ रहा है, इसलिए पाठक को बंद करने की कोई आवश्यकता नहीं है (और यह संभव नहीं है), और इसके बजाय file
खुद बंद होना चाहिए।[8]
<वाक्यविन्यास लैंग = अजगर>
f के रूप में खुले (फ़ाइल नाम) के साथ:
आर = सीएसवी.रीडर (एफ) # आर का प्रयोग करें।
- f बंद हो जाता है जब with-statement बाहर निकल जाता है, और अब इसका उपयोग नहीं किया जा सकता है।
- r के लिए कुछ भी नहीं किया गया है, लेकिन अंतर्निहित f बंद है, इसलिए r का उपयोग भी नहीं किया जा सकता है।
</वाक्यविन्यास हाइलाइट>
.NET Framework|.NET में, सम्मेलन केवल संसाधनों के प्रत्यक्ष उपयोगकर्ता के लिए ज़िम्मेदार है: आपको IDisposable केवल तभी लागू करना चाहिए जब आपका प्रकार सीधे अप्रबंधित संसाधनों का उपयोग करता हो।[9]
अधिक जटिल ऑब्जेक्ट ग्राफ़ के मामले में, जैसे संसाधनों को साझा करने वाली कई ऑब्जेक्ट, या संसाधनों को धारण करने वाली वस्तुओं के बीच चक्र, उचित संसाधन प्रबंधन काफी जटिल हो सकता है, और वास्तव में वही समस्याएँ उत्पन्न होती हैं जो ऑब्जेक्ट फ़ाइनलाइज़ेशन (विनाशकों या फ़ाइनलाइज़र के माध्यम से) में उत्पन्न होती हैं; उदाहरण के लिए, व्यपगत श्रोता समस्या हो सकती है और उपयोग करने पर संसाधन रिसाव का कारण बन सकती है
पर्यवेक्षक पैटर्न (और पर्यवेक्षकों के पास संसाधन हैं)। संसाधन प्रबंधन के अधिक नियंत्रण की अनुमति देने के लिए विभिन्न तंत्र मौजूद हैं। उदाहरण के लिए, Google क्लोजर लाइब्रेरी में, goog.Disposable
वर्ग प्रदान करता है registerDisposable
इस वस्तु के साथ निपटाने के लिए अन्य वस्तुओं को पंजीकृत करने की विधि, निपटान के प्रबंधन के लिए विभिन्न निम्न-स्तरीय उदाहरणों और वर्ग विधियों के साथ।
संरचित प्रोग्रामिंग
संरचित प्रोग्रामिंग में, सभी मामलों को संभालने के लिए पर्याप्त रूप से नेस्टिंग कोड द्वारा स्टैक संसाधन प्रबंधन किया जाता है। इसके लिए कोड के अंत में केवल एक वापसी की आवश्यकता होती है, और यदि बहुत सारे संसाधनों को प्राप्त किया जाना चाहिए, तो भारी नेस्टेड कोड हो सकता है, जिसे कुछ लोगों द्वारा एक विरोधी पैटर्न माना जाता है - एरोएंटीपैटर्न एरो एंटीपैटर्न,[10] क्रमिक नेस्टिंग से त्रिकोणीय आकार के कारण।
सफाई खंड
एक अन्य दृष्टिकोण, जो जल्दी वापसी की अनुमति देता है, लेकिन एक ही स्थान पर सफाई को समेकित करता है, एक फ़ंक्शन का एकल निकास रिटर्न है, जो सफाई कोड से पहले है, और बाहर निकलने से पहले सफाई पर कूदने के लिए के लिए जाओ का उपयोग करना है। यह आधुनिक कोड में शायद ही कभी देखा जाता है, लेकिन सी के कुछ उपयोगों में होता है।
यह भी देखें
- स्मृति प्रबंधन
- पूल (कंप्यूटर विज्ञान)
संदर्भ
- ↑ 1.0 1.1 1.2 Beck 1997, pp. 37–39.
- ↑ 2.0 2.1 Elder, Jackson & Liblit 2008, p. 3.
- ↑ Elder, Jackson & Liblit 2008, p. 2.
- ↑ "Generic: Change the Way You Write Exception-Safe Code — Forever", by Andrei Alexandrescu and Petru Marginean, December 01, 2000, Dr. Dobb's
- ↑ ScopeGuard 2.0, Joshua Lehrer
- ↑ D: Exception Safety
- ↑ Defer, Panic, and Recover, Andrew Gerrand, The Go Blog, 4 August 2010
- ↑ Python: No csv.close()?
- ↑ "आईडी डिस्पोजेबल इंटरफ़ेस". Retrieved 2016-04-03.
- ↑ Flattening Arrow Code, Jeff Atwood, 10 Jan 2006
- Beck, Kent (1997). Smalltalk Best Practice Patterns. Prentice Hall. ISBN 978-0134769042.
- Elder, Matt; Jackson, Steve; Liblit, Ben (October 2008). Code Sandwiches (PDF) (Technical report). University of Wisconsin–Madison. 1647, abstract
{{cite tech report}}
: External link in
(help)CS1 maint: postscript (link)|postscript=
अग्रिम पठन
इस पेज में लापता आंतरिक लिंक की सूची
- बाहर निकलें (सिस्टम कॉल)
- सबरूटीन
- अनुरेखण (सॉफ्टवेयर)
- प्रभुत्व
- प्रभुत्व (ग्राफ सिद्धांत)
- क्रम पर्यावरण
- दस्तावेज़ वस्तु मॉडल
- छोटी बात
- योजना (प्रोग्रामिंग भाषा)
- शून्य (प्रोग्रामिंग भाषा)
- प्रत्यक्ष शैली
- वस्तु रचना
- क्षेत्र (कंप्यूटर विज्ञान)
- वस्तु एकत्रीकरण
- पायथन (प्रोग्रामिंग भाषा)
- finalizer
- Encapsulation (कंप्यूटर प्रोग्रामिंग)