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

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

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