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

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

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

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

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

जबकि C और C ++ दोनों के द्वारा अभिप्रेत C मानक यह व्यक्त करने में विफल रहते हैं कि  सिमेंटिक्स लवल्यू को संदर्भित करता है, संदर्भित वस्तु को नहीं। संबंधित दोष रिपोर्ट DR 476 (C11 तक) अभी भी C17 (C मानक संशोधन) के साथ समीक्षाधीन है।

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

C में मेमोरी-मैप किए गए I/O का उदाहरण

इस उदाहरण में कोड में संग्रहीत मान  को  सेट करता है यह तब तक पोल (कंप्यूटर विज्ञान) आरम्भ करता है जब तक कि इसे परिवर्तित होने तक बार-बार    मूल्य नहीं मिलता:

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

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

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

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

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

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

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

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

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

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

केवल निम्न प्रकारों को चिह्नित किया जा सकता है: सभी संदर्भ प्रकार,,  ,  ,  ,  ,  ,  ,  ,  , और सभी प्रगणित प्रकार एक अंतर्निहित प्रकार के साथ  ,  ,  ,  ,  , या. (इसमें वैल्यू स्ट्रक्चर्स, साथ ही आदिम प्रकार सम्मिलित नहीं हैं,  ,   और  .)

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

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

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

वोलेटाइल का उपयोग कम करता है और अनुकूलन को रोक भी सकता है।

बाहरी संबंध

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