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

From Vigyanwiki

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

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

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

C और C ++ में

C और C ++ में volatile कीवर्ड का निम्नलिखित उद्देश्य था[1]

  • मेमोरी-मैप्ड I/O उपकरणों तक पहुंच की अनुमति देना।
  • setjmp और longjmp के मध्य चर के उपयोग की अनुमति देना।
  • sig_atomic_t सिग्नल हैंडलर में चर के उपयोग की अनुमति देना।

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

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


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

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

static int foo;

void bar(void) {
    foo = 0;

    while (foo != 255)
         ;
}

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

void bar_optimized(void) {
    foo = 0;

    while (true)
         ;
}

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

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

static volatile int foo;

void bar (void) {
    foo = 0;

    while (foo != 255)
        ;
}

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

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

C में अनुकूलन तुलना

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

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


C ++ 11

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


Java में

जावा प्रोग्रामिंग भाषा में भी volatile कीवर्ड है परन्तु इसका उपयोग कुछ विभिन्न उद्देश्य के लिए किया जाता है। जब किसी क्षेत्र में लागू किया जाता है तो जावा क्वालीफायर volatile निम्नलिखित गारंटी प्रदान करता है:

  • जावा के सभी संस्करणों में सभी वोलेटाइल चरों के पढ़ने और लिखने पर एक वैश्विक क्रम है (वोलेटाइल पर यह वैश्विक क्रम बड़े तुल्यकालन क्रम पर आंशिक क्रम है (जो सभी तुल्यकालन क्रियाओं पर कुल क्रम है))। इसका तात्पर्य है कि प्रत्येक थ्रेड (कंप्यूटर विज्ञान) वोलेटाइल क्षेत्र तक पहुँचने से पहले कैच मान का उपयोग करने के स्थान पर (संभावित रूप से) जारी रखने से पहले अपने वर्तमान मूल्य को पढ़ेगा। (जबकि नियमित पढ़ने और लिखने के साथ वोलेटाइल पढ़ने और लिखने के सापेक्ष क्रम के बारे में कोई गारंटी नहीं है जिसका अर्थ है कि यह सामान्य रूप से उपयोगी थ्रेडिंग निर्माण नहीं है।)
  • जावा 5 या उसके बाद का वोलेटाइल पढ़ता है और लिखता है तथा म्यूटेक्स को प्राप्त करने और जारी करने की तरह पहले संबंध स्थापित करता है।[8][9]

volatile का उपयोग करते हुए लॉक (कंप्यूटर विज्ञान) से तीव्र हो सकता है परन्तु यह जावा 5 से पहले कुछ स्थितियों में काम नहीं करेगा।[10] जावा 5 में वोलेटाइल स्थितियों की श्रेणी का विस्तार किया गया था; विशेष रूप से, डबल-चेक लॉकिंग अब सही प्रकार से काम करती है।[11]

C# में

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

volatile केवल निम्न प्रकारों को चिह्नित किया जा सकता है: सभी संदर्भ प्रकार, Single, Boolean, Byte, SByte, Int16, UInt16, Int32, UInt32, Char, और सभी प्रगणित प्रकार एक अंतर्निहित प्रकार के साथ Byte, SByte, Int16, UInt16, Int32, या UInt32.[13] (इसमें वैल्यू स्ट्रक्चर्स, साथ ही आदिम प्रकार सम्मिलित नहीं हैं Double, Int64, UInt64 और Decimal.)

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

वास्तव में ये विधियाँ सामान्यतः C # कंपाइलर, JIT कंपाइलर या स्वयं CPU द्वारा किए गए कुछ अनुकूलन को अक्षम कर देती हैं। Thread.VolatileReadद्वारा प्रदान की गई गारंटी और Thread.VolatileWrite द्वारा प्रदान की गई गारंटी volatile कीवर्ड का सुपरसेट है: आधा फेंस उत्पन्न करने के स्थान पर (अर्थात अधिग्रहण-फेंस केवल निर्देश पुनर्व्यवस्था और कैचिंग को रोकता है जो इससे पहले आता है), VolatileRead और VolatileWrite पूर्ण फेंस उत्पन्न करते हैं जो दोनों दिशाओं में उस क्षेत्र के निर्देश पुनर्क्रमण और कैचिंग को रोकता है।[12] ये उपाय इस प्रकार कार्य करते हैं:[14]

  • Thread.VolatileWrite विधि फ़ील्ड में मान को कॉल के बिंदु पर लिखे जाने के लिए बाध्य करती है। इसके अतिरिक्त किसी भी पुराने प्रोग्राम-ऑर्डर लोड और स्टोर को कॉल करने से पहले VolatileWriteहोना चाहिए और किसी भी बाद के प्रोग्राम-ऑर्डर लोड और स्टोर कॉल के बाद होने चाहिए।
  • Thread.VolatileRead विधि कॉल के बिंदु पर फ़ील्ड में मान को पढ़ने के लिए बाध्य करती है। इसके अलावा, किसी भी पुराने प्रोग्राम-ऑर्डर लोड और स्टोर को कॉल करने से पहले होना चाहिए VolatileRead और किसी भी बाद के प्रोग्राम-ऑर्डर लोड और स्टोर कॉल के बाद होने चाहिए। Thread.VolatileRead और Thread.VolatileWrite विधियाँ कॉल करके एक पूर्ण फेंस उत्पन्न करती हैं Thread.MemoryBarrier विधि जो मेमोरी बैरियर का निर्माण करती है जो दोनों दिशाओं में काम करती है। ऊपर दिए गए पूर्ण फेंस का उपयोग करने के लिए प्रेरणाओं के अतिरिक्त एक संभावित समस्या volatile द्वारा उत्पन्न एक पूर्ण फेंस का उपयोग करके हल किया गया कीवर्ड Thread.MemoryBarrier इस प्रकार है: आधा फेंस की असममित प्रकृति के कारण, volatile पढ़ने के निर्देश के पश्चात लेखन निर्देश के साथ फ़ील्ड में अभी भी संकलक द्वारा निष्पादन आदेश स्वैप किया जा सकता है। क्योंकि पूर्ण फेंस सममित हैं, Thread.MemoryBarrierउपयोग करते समय यह कोई समस्या नहीं है। [12]

फोरट्रान में

VOLATILE फोरट्रान 2003 मानक का भाग है[15] जबकि पहले के संस्करण ने इसे विस्तार के रूप में समर्थित किया था। सभी volatileचर बनाना किसी फ़ंक्शन में अलियासिंग (कंप्यूटिंग) संबंधित बग खोजने में भी उपयोगी है।

integer, volatile :: i ! When not defined volatile the following two lines of code are identical
write(*,*) i**2  ! Loads the variable i once from memory and multiplies that value times itself
write(*,*) i*i   ! Loads the variable i twice from memory and multiplies those values

सदैव VOLATILE की मेमोरी में ड्रिलिंग करके फोरट्रान कंपाइलर को पढ़ने या लिखने के लिए वोलेटाइल को पुनः व्यवस्थित करने से रोक दिया जाता है। यह इस थ्रेड में की गई अन्य थ्रेड और इसके विपरीत क्रियाओं को दिखाई देता है।[16]

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


संदर्भ

  1. 1.0 1.1 "सी++ मानक समिति पर प्रकाशन".
  2. Clarification Request Summary for C11. Version 1.13, October 2017.
  3. "विज़ुअल सी ++ में वाष्पशील कीवर्ड". Microsoft MSDN.
  4. "Linux Kernel Documentation – Why the "volatile" type class should not be used". kernel.org.
  5. Scott Meyers; Andrei Alexandrescu (2004). "सी++ और डबल-चेक्ड लॉकिंग के खतरे" (PDF). DDJ.
  6. Jeremy Andrews (2007). "Linux: Volatile Superstition". kerneltrap.org. Archived from the original on 2010-06-20. Retrieved Jan 9, 2011.
  7. "अस्थिर (सी ++)". Microsoft MSDN.
  8. Section 17.4.4: Synchronization Order "The Java® Language Specification, Java SE 7 Edition". Oracle Corporation. 2013. Retrieved 2013-05-12.
  9. "Java Concurrency: Understanding the 'Volatile' Keyword". dzone.com. 2021-03-08. Archived from the original on 2021-05-09. Retrieved 2021-05-09.
  10. Jeremy Manson; Brian Goetz (February 2004). "JSR 133 (Java Memory Model) FAQ". Archived from the original on 2021-05-09. Retrieved 2019-11-05.
  11. Neil Coffey. "Double-checked Locking (DCL) and how to fix it". Javamex. Retrieved 2009-09-19.
  12. 12.0 12.1 12.2 12.3 Albahari, Joseph. "Part 4: Advanced Threading". Threading in C#. O'Reilly Media. Archived from the original on 12 December 2019. Retrieved 9 December 2019.{{cite web}}: CS1 maint: bot: original URL status unknown (link)
  13. Richter, Jeffrey (February 11, 2010). "Chapter 7: Constants and Fields". सीएलआर के माध्यम से सी#. Microsoft Press. pp. 183. ISBN 978-0-7356-2704-8.
  14. Richter, Jeffrey (February 11, 2010). "Chapter 28: Primitive Thread Synchronization Constructs". सीएलआर के माध्यम से सी#. Microsoft Press. pp. 797–803. ISBN 978-0-7356-2704-8.
  15. "वाष्पशील विशेषता और कथन". Cray. Archived from the original on 2018-01-23. Retrieved 2016-04-22.
  16. "फोरट्रान में अस्थिर और साझा सरणी". Intel.com.
  17. "परिवर्तनशील". Oracle.com.


बाहरी संबंध