वोलेटाइल (कंप्यूटर प्रोग्रामिंग)

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

C ( प्रोग्रामिंग भाषा ), C++, C Sharp (प्रोग्रामिंग लैंग्वेज) | C#, और Java (प्रोग्रामिंग लैंग्वेज) प्रोग्रामिंग लैंग्वेज में, वोलेटाइल कीवर्ड (कंप्यूटर प्रोग्रामिंग) इंगित करता है कि एक मूल्य (कंप्यूटर विज्ञान)  अलग-अलग एक्सेस के बीच बदल सकती है, यहां तक ​​​​कि अगर यह संशोधित प्रतीत नहीं होता है। यह कीवर्ड एक अनुकूलन संकलक को बाद के रीड्स या राइट्स को ऑप्टिमाइज़ करने से रोकता है और इस तरह गलत तरीके से एक बासी मान का पुन: उपयोग करता है या राइट्स को छोड़ देता है। वाष्पशील मान मुख्य रूप से हार्डवेयर एक्सेस (मेमोरी-मैप्ड I/O) में उत्पन्न होते हैं, जहां मेमोरी से पढ़ने या लिखने का उपयोग परिधीय उपकरणों के साथ संवाद करने के लिए किया जाता है, और थ्रेड (कंप्यूटिंग) में, जहां एक अलग थ्रेड ने मान को संशोधित किया हो।

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

सी और सी ++
में

सी में, और फलस्वरूप सी ++,  कीवर्ड का इरादा था
 * मेमोरी-मैप्ड I/O उपकरणों तक पहुंच की अनुमति दें
 * के बीच चर के उपयोग की अनुमति दें  और
 * के उपयोग की अनुमति दें  सिग्नल हैंडलर में चर।

जबकि सी और सी ++ दोनों का इरादा है, सी मानक यह व्यक्त करने में विफल रहते हैं कि  सिमेंटिक्स लवल्यू को संदर्भित करता है, संदर्भित वस्तु को नहीं। संबंधित दोष रिपोर्ट DR 476 (C11 तक) अभी भी C17 (C मानक संशोधन) के साथ समीक्षाधीन है। संचालन चालू  चर परमाणु संचालन नहीं हैं, और न ही वे थ्रेडिंग के लिए उचित होता है-पहले संबंध स्थापित करते हैं। यह प्रासंगिक मानकों (C, C++, POSIX, WIN32) में निर्दिष्ट है, और अस्थिर चर मौजूदा कार्यान्वयन के विशाल बहुमत में थ्रेडसेफ नहीं हैं। इस प्रकार, का उपयोग   पोर्टेबल सिंक्रनाइज़ेशन तंत्र के रूप में कीवर्ड को कई सी/सी ++ समूहों द्वारा निराश किया जाता है।

सी
में मेमोरी-मैप किए गए I/O का उदाहरण इस उदाहरण में, कोड में संग्रहीत मान सेट करता है  को. यह तब तक मतदान (कंप्यूटर विज्ञान) शुरू करता है जब तक कि इसे बदलने तक बार-बार मूल्य नहीं मिलता :

एक ऑप्टिमाइज़िंग कंपाइलर नोटिस करेगा कि कोई अन्य कोड संभवतः संग्रहीत मान को बदल नहीं सकता है, और मान लेंगे कि यह बराबर रहेगा   हर समय। इसलिए कंपाइलर फ़ंक्शन बॉडी को इसके समान एक अनंत लूप से बदल देगा:

हालाँकि,  एक ऐसे स्थान का प्रतिनिधित्व कर सकता है जिसे किसी भी समय कंप्यूटर सिस्टम के अन्य तत्वों द्वारा बदला जा सकता है, जैसे कि  CPU  से जुड़े डिवाइस का हार्डवेयर रजिस्टर। उपरोक्त कोड ऐसे परिवर्तन का कभी पता नहीं लगाएगा; के बिना   कीवर्ड, कंपाइलर मानता है कि वर्तमान प्रोग्राम सिस्टम का एकमात्र हिस्सा है जो मूल्य को बदल सकता है (जो अब तक की सबसे आम स्थिति है)।

ऊपर के रूप में कोड को अनुकूलित करने से संकलक को रोकने के लिए,  कीवर्ड प्रयोग किया जाता है:

इस संशोधन के साथ लूप की स्थिति को अनुकूलित नहीं किया जाएगा, और जब यह होता है तो सिस्टम परिवर्तन का पता लगाएगा।

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

सी
में अनुकूलन तुलना निम्नलिखित सी कार्यक्रम, और साथ में असेंबलर भाषा अंश, प्रदर्शित करते हैं कि कैसे  कीवर्ड कंपाइलर के आउटपुट को प्रभावित करता है। इस मामले में संकलक GNU संकलक संग्रह था।

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

सी ++ 11
C++11 ISO मानक के अनुसार, अस्थिर कीवर्ड केवल हार्डवेयर एक्सेस के लिए उपयोग के लिए है; इंटर-थ्रेड संचार के लिए इसका इस्तेमाल न करें। इंटर-थ्रेड संचार के लिए, मानक पुस्तकालय प्रदान करता है  टेम्पलेट्स।

जावा में
जावा प्रोग्रामिंग भाषा में भी है  कीवर्ड, लेकिन इसका उपयोग कुछ अलग उद्देश्य के लिए किया जाता है। जब किसी क्षेत्र में लागू किया जाता है, तो जावा क्वालीफायर   निम्नलिखित गारंटी प्रदान करता है: का उपयोग करते हुए   ताला (कंप्यूटर विज्ञान)  से तेज हो सकता है, लेकिन यह जावा 5 से पहले कुछ स्थितियों में काम नहीं करेगा। जावा 5 में अस्थिर स्थितियों की श्रेणी का विस्तार किया गया था; विशेष रूप से, डबल-चेक लॉकिंग अब सही तरीके से काम करती है।
 * जावा के सभी संस्करणों में, सभी वाष्पशील चरों के पढ़ने और लिखने पर एक वैश्विक क्रम है (वाष्पशील पर यह वैश्विक क्रम बड़े तुल्यकालन क्रम पर एक आंशिक क्रम है (जो सभी तुल्यकालन क्रियाओं पर कुल क्रम है))। इसका तात्पर्य है कि प्रत्येक थ्रेड (कंप्यूटर विज्ञान) एक अस्थिर क्षेत्र तक पहुँचने से पहले एक कैश्ड मान का उपयोग करने के बजाय (संभावित रूप से) जारी रखने से पहले अपने वर्तमान मूल्य को पढ़ेगा। (हालांकि, नियमित पढ़ने और लिखने के साथ अस्थिर पढ़ने और लिखने के सापेक्ष क्रम के बारे में कोई गारंटी नहीं है, जिसका अर्थ है कि यह आम तौर पर उपयोगी थ्रेडिंग निर्माण नहीं है।)
 * जावा 5 या बाद में, अस्थिर पढ़ता है और लिखता है एक हुआ-पहले | होता है-पहले संबंध स्थापित करता है, एक म्यूटेक्स को प्राप्त करने और जारी करने की तरह।

सी #
में

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

का उपयोग  कीवर्ड उन क्षेत्रों का समर्थन नहीं करता है जो मूल्यांकन रणनीति हैं #संदर्भ या क्लोजर (कंप्यूटर प्रोग्रामिंग) द्वारा कॉल करें; ऐसे मामलों में,   और   की जगह इस्तेमाल करना चाहिए।

वास्तव में, ये विधियाँ आमतौर पर C # कंपाइलर, JIT कंपाइलर या स्वयं CPU द्वारा किए गए कुछ अनुकूलन को अक्षम कर देती हैं। द्वारा प्रदान की गई गारंटी  और   द्वारा प्रदान की गई गारंटी का सुपरसेट है   कीवर्ड: आधा बाड़ उत्पन्न करने के बजाय (यानी एक अधिग्रहण-बाड़ केवल निर्देश पुनर्व्यवस्था और कैशिंग को रोकता है जो इससे पहले आता है),   और   एक पूर्ण बाड़ उत्पन्न करें जो दोनों दिशाओं में उस क्षेत्र के निर्देश पुनर्क्रमण और कैशिंग को रोकता है। ये तरीके इस प्रकार काम करते हैं:
 * e> विधि फ़ील्ड में मान को कॉल के बिंदु पर लिखे जाने के लिए बाध्य करती है। इसके अलावा, किसी भी पुराने प्रोग्राम-ऑर्डर लोड और स्टोर को कॉल करने से पहले होना चाहिए  और किसी भी बाद के प्रोग्राम-ऑर्डर लोड और स्टोर कॉल के बाद होने चाहिए।
 * e> विधि कॉल के बिंदु पर फ़ील्ड में मान को पढ़ने के लिए बाध्य करती है। इसके अलावा, किसी भी पुराने प्रोग्राम-ऑर्डर लोड और स्टोर को कॉल करने से पहले होना चाहिए  और किसी भी बाद के प्रोग्राम-ऑर्डर लोड और स्टोर कॉल के बाद होने चाहिए।   ई> और   विधियाँ कॉल करके एक पूर्ण बाड़ उत्पन्न करती हैं   विधि, जो एक मेमोरी बैरियर का निर्माण करती है जो दोनों दिशाओं में काम करती है। ऊपर दिए गए पूर्ण बाड़ का उपयोग करने के लिए प्रेरणाओं के अलावा, एक संभावित समस्या   द्वारा उत्पन्न एक पूर्ण बाड़ का उपयोग करके हल किया गया कीवर्ड   इस प्रकार है: आधा बाड़ की असममित प्रकृति के कारण, ए   पढ़ने के निर्देश के बाद एक लेखन निर्देश के साथ फ़ील्ड में अभी भी संकलक द्वारा निष्पादन आदेश स्वैप किया जा सकता है। क्योंकि पूर्ण बाड़ सममित हैं, उपयोग करते समय यह कोई समस्या नहीं है.

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

बाहरी संबंध

 * Ada Reference Manual C.6: Shared Variable Control
 * Linux kernel: volatile-considered-harmful