थ्रेड-लोकल स्टोरेज: Difference between revisions

From Vigyanwiki
No edit summary
No edit summary
Line 2: Line 2:




[[कंप्यूटर प्रोग्रामिंग]] में, थ्रेड-लोकल स्टोरेज (TLS) एक [[ स्मृति प्रबंधन |स्मृति प्रबंधन]] मेथड है जो [[स्थैतिक स्मृति आवंटन]] या ग्लोबल [[ कंप्यूटर भंडारण |कंप्यूटर भंडारण]] को [[थ्रेड (कंप्यूटिंग)]] के लिए लोकल का उपयोग करता है।
[[कंप्यूटर प्रोग्रामिंग]] में, '''थ्रेड-लोकल स्टोरेज''' (TLS) एक [[ स्मृति प्रबंधन |मेमोरी  मैनेजमेंट]] मेथड है जो [[स्थैतिक स्मृति आवंटन|स्थैतिक मेमोरी  '''आवंटन''']] या ग्लोबल [[ कंप्यूटर भंडारण |कंप्यूटर स्टोरेज]] को [[थ्रेड (कंप्यूटिंग)]] के लिए लोकल का उपयोग करता है।


जबकि आधुनिक प्रोग्रामिंग में [[वैश्विक चर]]ों के उपयोग को आम तौर पर हतोत्साहित किया जाता है, [[UNIX]] जैसे लीगेसी ऑपरेटिंग सिस्टम को [[यूनिप्रोसेसर]] हार्डवेयर के लिए डिज़ाइन किया गया है और प्री-रीएंट्रेंसी (कंप्यूटिंग) एपीआई के शब्दार्थ को बनाए रखने के लिए कुछ अतिरिक्त तंत्र की आवश्यकता होती है। ऐसी स्थितियों का एक उदाहरण है जहां फ़ंक्शन त्रुटि स्थिति सेट करने के लिए वैश्विक चर का उपयोग करते हैं (उदाहरण के लिए वैश्विक चर <code>[[errno]]</code> [[ सी पुस्तकालय |सी पुस्तकालय]] के कई कार्यों द्वारा उपयोग किया जाता है)। अगर <code>errno</code> एक वैश्विक चर थे, एक थ्रेड पर एक सिस्टम फ़ंक्शन की कॉल किसी भिन्न थ्रेड पर सिस्टम फ़ंक्शन के कॉल द्वारा पहले सेट किए गए मान को अधिलेखित कर सकती है, संभवत: उस भिन्न थ्रेड पर कोड का पालन करने से पहले त्रुटि स्थिति की जांच कर सकती है। समाधान होना है <code>errno</code> ऐसा चर हो जो ऐसा लगता है कि यह वैश्विक है, लेकिन वास्तव में प्रति थ्रेड एक बार मौजूद है- यानी, यह थ्रेड-लोकल स्टोरेज में रहता है। एक दूसरा उपयोग मामला एक वैश्विक चर में जानकारी जमा करने वाले कई सूत्र होंगे। [[दौड़ की स्थिति]] से बचने के लिए, इस वैश्विक चर की प्रत्येक पहुंच को एक लॉक (कंप्यूटर विज्ञान) द्वारा संरक्षित करना होगा। वैकल्पिक रूप से, प्रत्येक थ्रेड एक थ्रेड-लोकल वेरिएबल में जमा हो सकता है (जो कि, परिभाषा के अनुसार, अन्य थ्रेड्स से पढ़ा या लिखा नहीं जा सकता है, जिसका अर्थ है कि दौड़ की स्थिति नहीं हो सकती है)। थ्रेड्स को केवल अपने स्वयं के थ्रेड-स्थानीय चर से एक एकल, सही मायने में वैश्विक चर में अंतिम संचय को सिंक्रनाइज़ करना होगा।
जबकि आधुनिक प्रोग्रामिंग में [[वैश्विक चर|ग्लोबल  वेरिएबल]] के उपयोग को समान्यत: हतोत्साहित किया जाता है, [[UNIX|यूनिक्स]] जैसे लीगेसी ऑपरेटिंग सिस्टम को [[यूनिप्रोसेसर]] हार्डवेयर के लिए डिज़ाइन किया गया है और प्री-रीएंट्रेंसी (कंप्यूटिंग) एपीआई के शब्दार्थ को बनाए रखने के लिए कुछ अतिरिक्त तंत्र की आवश्यकता होती है। ऐसी स्थितियों का एक उदाहरण है जहां फ़ंक्शन त्रुटि स्थिति सेट करने के लिए ग्लोबल  वेरिएबल  का उपयोग करते हैं (उदाहरण के लिए ग्लोबल  वेरिएबल  <code>[[errno]]</code> [[ सी पुस्तकालय |c लाइब्रेरी]] के कई कार्यों द्वारा उपयोग किया जाता है)। यदि <code>errno</code> एक ग्लोबल  वेरिएबल  थे, एक थ्रेड पर एक सिस्टम फ़ंक्शन की कॉल किसी भिन्न थ्रेड पर सिस्टम फ़ंक्शन के कॉल द्वारा पहले सेट किए गए मान को अधिलेखित कर सकती है, संभवत: उस भिन्न थ्रेड पर कोड का पालन करने से पहले त्रुटि स्थिति की जांच कर सकती है। जिसका समाधान होना है <code>errno</code> ऐसा वेरिएबल  हो जो ऐसा लगता है कि यह ग्लोबल  है, किंतु वास्तव में प्रति थ्रेड एक बार उपस्थित है- अथार्त यह थ्रेड-लोकल स्टोरेज में रहता है। एक दूसरा उपयोग स्थिति एक ग्लोबल  वेरिएबल  में जानकारी जमा करने वाले कई सूत्र होंगे। [[दौड़ की स्थिति|रेस कंडीशन]] से बचने के लिए, इस ग्लोबल  वेरिएबल  की प्रत्येक पहुंच को एक लॉक (कंप्यूटर विज्ञान) द्वारा संरक्षित करना होगा। वैकल्पिक रूप से, प्रत्येक थ्रेड एक थ्रेड-लोकल वेरिएबल में जमा हो सकता है (जो कि, परिलैंग्वेज के अनुसार, अन्य थ्रेड्स से पढ़ा या लिखा नहीं जा सकता है, जिसका अर्थ है कि [[दौड़ की स्थिति|रेस कंडीशन]] नहीं हो सकती है)। थ्रेड्स को केवल अपने स्वयं के थ्रेड-स्थानीय वेरिएबल  से एक एकल, सही विधि में ग्लोबल  वेरिएबल  में अंतिम संचय को सिंक्रनाइज़ करना होगा।


कई प्रणालियाँ थ्रेड-लोकल मेमोरी ब्लॉक के आकार पर प्रतिबंध लगाती हैं, वास्तव में अक्सर बल्कि तंग सीमाएँ। दूसरी ओर, यदि कोई सिस्टम कम से कम एक [[ स्मृति पता |स्मृति पता]] (पॉइंटर) आकार का वेरिएबल थ्रेड-लोकल प्रदान कर सकता है, तो यह मनमाने ढंग से आकार के मेमोरी ब्लॉक को थ्रेड-लोकल तरीके से उपयोग करने की अनुमति देता है, इस तरह के मेमोरी ब्लॉक को गतिशील रूप से आवंटित करके और स्टोर करके थ्रेड-लोकल वैरिएबल में उस ब्लॉक का मेमोरी एड्रेस। कम निर्देश सेट कंप्यूटर मशीनों पर, [[कॉलिंग कन्वेंशन]] अक्सर इस उपयोग के लिए थ्रेड पॉइंटर रजिस्टर आरक्षित करता है।
कई प्रणालियाँ थ्रेड-लोकल मेमोरी ब्लॉक के आकार पर प्रतिबंध लगाती हैं, वास्तव में अधिकांशतः किंतु तंग सीमाएँ दूसरी ओर, यदि कोई सिस्टम कम से कम एक [[ स्मृति पता |मेमोरी  एड्रेस]] (पॉइंटर) आकार का वेरिएबल थ्रेड-लोकल प्रदान कर सकता है, तो यह इच्छित रूप से आकार के मेमोरी ब्लॉक को थ्रेड-लोकल विधि  से उपयोग करने की अनुमति देता है, इस तरह के मेमोरी ब्लॉक को गतिशील रूप से आवंटित करके और स्टोर करके थ्रेड-लोकल वैरिएबल में उस ब्लॉक का मेमोरी एड्रेस कम निर्देश सेट कंप्यूटर मशीनों पर, [[कॉलिंग कन्वेंशन]] अधिकांशतः इस उपयोग के लिए थ्रेड पॉइंटर रजिस्टर आरक्षित करता है।


== विंडोज कार्यान्वयन ==
== विंडोज कार्यान्वयन ==
[[अप्लिकेशन प्रोग्रामिंग अंतरफलक]] (एपीआई) फ़ंक्शन <code>TlsAlloc</code> अप्रयुक्त टीएलएस स्लॉट इंडेक्स प्राप्त करने के लिए इस्तेमाल किया जा सकता है; तब TLS स्लॉट इंडेक्स को 'प्रयुक्त' माना जाएगा। <code>TlsGetValue</code> ई> और <code>TlsSetValue</code> फ़ंक्शंस का उपयोग तब TLS स्लॉट इंडेक्स द्वारा पहचाने गए थ्रेड-लोकल वैरिएबल को मेमोरी एड्रेस पढ़ने और लिखने के लिए किया जाता है। <code>TlsSetValue</code> केवल वर्तमान थ्रेड के लिए वेरिएबल को प्रभावित करता है। <code>TlsFree</code> टीएलएस स्लॉट इंडेक्स जारी करने के लिए ई> फ़ंक्शन को कॉल किया जा सकता है।
एप्लिकेशन प्रोग्रामिंग इंटरफ़ेस (एपीआई) फ़ंक्शन <code>TlsAlloc</code> का उपयोग अप्रयुक्त टीएलएस स्लॉट इंडेक्स प्राप्त करने के लिए किया जा सकता है; टीएलएस स्लॉट इंडेक्स को तब 'प्रयुक्त' माना जाएगा।


प्रत्येक थ्रेड के लिए एक [[Win32 थ्रेड सूचना ब्लॉक]] है। इस ब्लॉक में प्रविष्टियों में से एक उस थ्रेड के लिए थ्रेड-लोकल स्टोरेज टेबल है।<ref>{{cite web|url=http://www.microsoft.com/msj/archive/s2ce.aspx|website=[[MSDN]]|access-date=6 April 2010|date=May 2006|title=हुड के नीचे|last=Pietrek|first=Matt|author-link=Matt Pietrek}}</ref>
<code>TlsGetValue</code> और <code>TlsSetValue</code> फ़ंक्शंस का उपयोग टीएलएस स्लॉट इंडेक्स द्वारा पहचाने गए थ्रेड-लोकल वेरिएबल में मेमोरी एड्रेस को पढ़ने और लिखने के लिए किया जाता है। <code>TlsSetValue</code> केवल वर्तमान थ्रेड के वेरिएबल को प्रभावित करता है। टीएलएस स्लॉट इंडेक्स जारी करने के लिए <code>TlsFree</code> फ़ंक्शन को कॉल किया जा सकता है।
TlsAlloc प्रत्येक कॉल के लिए इस तालिका में एक अनुक्रमणिका लौटाता है, अद्वितीय प्रति पता स्थान। प्रत्येक थ्रेड के पास थ्रेड-लोकल स्टोरेज टेबल की अपनी कॉपी होती है। इसलिए, प्रत्येक थ्रेड स्वतंत्र रूप से TlsSetValue(index) का उपयोग कर सकता है और TlsGetValue(index) के माध्यम से निर्दिष्ट मान प्राप्त कर सकता है, क्योंकि ये थ्रेड की अपनी तालिका में एक प्रविष्टि सेट और खोजते हैं।


TlsXxx ​​फ़ंक्शन परिवार के अलावा, विंडोज़ एक्जीक्यूटेबल्स एक सेक्शन को परिभाषित कर सकते हैं जो निष्पादन प्रक्रिया के प्रत्येक थ्रेड के लिए एक अलग पृष्ठ पर मैप किया गया है। TlsXxx ​​मानों के विपरीत, इन पृष्ठों में मनमाने और वैध पते हो सकते हैं। हालाँकि, ये पते प्रत्येक निष्पादन थ्रेड के लिए अलग-अलग हैं और इसलिए एसिंक्रोनस फ़ंक्शंस (जो एक अलग थ्रेड में निष्पादित हो सकते हैं) या अन्यथा कोड को पास नहीं किया जाना चाहिए, जो मानते हैं कि पूरी प्रक्रिया के भीतर एक वर्चुअल एड्रेस अद्वितीय है। TLS अनुभागों को [[पेजिंग]] का उपयोग करके प्रबंधित किया जाता है और इसका आकार पृष्ठ आकार (x86 मशीनों पर 4kB) तक निर्धारित किया जाता है।
प्रत्येक थ्रेड के लिए एक [[Win32 थ्रेड सूचना ब्लॉक|विन32 थ्रेड सूचना ब्लॉक]] है। इस ब्लॉक में प्रविष्टियों में से एक उस थ्रेड के लिए थ्रेड-लोकल स्टोरेज टेबल है।<ref>{{cite web|url=http://www.microsoft.com/msj/archive/s2ce.aspx|website=[[MSDN]]|access-date=6 April 2010|date=May 2006|title=हुड के नीचे|last=Pietrek|first=Matt|author-link=Matt Pietrek}}</ref> TlsAlloc प्रत्येक कॉल के लिए इस तालिका में एक अनुक्रमणिका लौटाता है, अद्वितीय प्रति एड्रेस  स्थान प्रत्येक थ्रेड के पास थ्रेड-लोकल स्टोरेज टेबल की अपनी कॉपी होती है। इसलिए, प्रत्येक थ्रेड स्वतंत्र रूप से TlsSetValue(index) का उपयोग कर सकता है और TlsGetValue(index) के माध्यम से निर्दिष्ट मान प्राप्त कर सकता है, क्योंकि ये थ्रेड की अपनी तालिका में एक प्रविष्टि सेट और खोजते हैं।
इस तरह के अनुभागों को केवल एक प्रोग्राम के मुख्य निष्पादन योग्य के अंदर परिभाषित किया जा सकता है - [[डायनामिक-लिंक लाइब्रेरी]] में ऐसे अनुभाग नहीं होने चाहिए, क्योंकि लोड लाइब्रेरी के साथ लोड करते समय उन्हें सही ढंग से प्रारंभ नहीं किया जाता है।
 
TlsXxx ​​फ़ंक्शन वर्ग के अतिरिक्त, विंडोज़ एक्जीक्यूटेबल्स एक सेक्शन को परिभाषित कर सकते हैं जो निष्पादन प्रक्रिया के प्रत्येक थ्रेड के लिए एक अलग पृष्ठ पर मैप किया गया है। TlsXxx ​​मानों के विपरीत, इन पृष्ठों में इच्छित और वैध पते हो सकते हैं। चूँकि  ये पते प्रत्येक निष्पादन थ्रेड के लिए अलग-अलग हैं और इसलिए एसिंक्रोनस फ़ंक्शंस (जो एक अलग थ्रेड में निष्पादित हो सकते हैं) या अन्यथा कोड को पास नहीं किया जाना चाहिए, जो मानते हैं कि पूरी प्रक्रिया के अंदर एक वर्चुअल एड्रेस अद्वितीय है। टीएलएस अनुभागों को [[पेजिंग]] का उपयोग करके प्रबंधित किया जाता है और इसका आकार पृष्ठ आकार (x86 मशीनों पर 4kB) तक निर्धारित किया जाता है। इस तरह के अनुभागों को केवल एक प्रोग्राम के मुख्य निष्पादन योग्य के अंदर परिभाषित किया जा सकता है - [[डायनामिक-लिंक लाइब्रेरी]] में ऐसे अनुभाग नहीं होने चाहिए, क्योंकि लोड लाइब्रेरी के साथ लोड करते समय उन्हें सही रूप से प्रारंभ नहीं किया जाता है।


== पीथ्रेड्स कार्यान्वयन ==
== पीथ्रेड्स कार्यान्वयन ==
[[Pthreads]] API में, थ्रेड के लिए स्थानीय मेमोरी को थ्रेड-विशिष्ट डेटा शब्द के साथ नामित किया गया है।
[[Pthreads]] API में, थ्रेड के लिए स्थानीय मेमोरी को थ्रेड-विशिष्ट डेटा शब्द के साथ नामित किया गया है।


कार्य <code>pthread_key_create</code> और <code>pthread_key_delete</code> थ्रेड-विशिष्ट डेटा के लिए कुंजी बनाने और हटाने के लिए क्रमशः उपयोग किया जाता है। कुंजी का प्रकार स्पष्ट रूप से अपारदर्शी छोड़ दिया जाता है और इसे कहा जाता है <code>pthread_key_t</code>. यह कुंजी सभी धागों द्वारा देखी जा सकती है। प्रत्येक थ्रेड में, कुंजी को थ्रेड-विशिष्ट डेटा के माध्यम से जोड़ा जा सकता है <code>pthread_setspecific</code>. डेटा को बाद में उपयोग करके पुनर्प्राप्त किया जा सकता है <code>pthread_getspecific</code>.
थ्रेड-विशिष्ट डेटा के लिए कुंजी बनाने और हटाने के लिए क्रमशः <code>pthread_key_create</code> and <code>pthread_key_delete</code> फ़ंक्शन का उपयोग किया जाता है। कुंजी का प्रकार स्पष्ट रूप से अपारदर्शी छोड़ दिया गया है और इसे <code>pthread_key_t</code>कहा जाता है। इस कुंजी को सभी थ्रेड्स द्वारा देखा जा सकता है। प्रत्येक थ्रेड में, कुंजी को <code>pthread_setspecific</code> के माध्यम से थ्रेड-विशिष्ट डेटा से जोड़ा जा सकता है। डेटा को बाद में <code>pthread_getspecific</code>. का उपयोग करके पुनर्प्राप्त किया जा सकता है।


इसके साथ ही <code>pthread_key_create</code> यदि थ्रेड-विशिष्ट डेटा NULL नहीं है, तो वैकल्पिक रूप से एक विध्वंसक फ़ंक्शन को स्वीकार कर सकता है, जिसे थ्रेड निकास पर स्वचालित रूप से कॉल किया जाएगा। विध्वंसक कुंजी के साथ जुड़े मान को पैरामीटर के रूप में प्राप्त करता है ताकि यह क्लीनअप क्रियाएं (करीब कनेक्शन, मुक्त मेमोरी, आदि) कर सके। यहां तक ​​​​कि जब एक विनाशक निर्दिष्ट किया जाता है, तब भी प्रोग्राम को कॉल करना चाहिए <code>pthread_key_delete</code> थ्रेड-विशिष्ट डेटा को प्रक्रिया स्तर पर मुक्त करने के लिए (विध्वंसक केवल थ्रेड के लिए स्थानीय डेटा को मुक्त करता है)।
इसके अतिरिक्त <code>pthread_key_create</code> वैकल्पिक रूप से एक डिस्ट्रक्टर फ़ंक्शन को स्वीकार कर सकता है जिसे थ्रेड-विशिष्ट डेटा NULL नहीं होने पर थ्रेड निकास पर स्वचालित रूप से कॉल किया जाएगा। विध्वंसक कुंजी से जुड़े मान को पैरामीटर के रूप में प्राप्त करता है जिससे वह सफाई क्रियाएं (संवर्त कनेक्शन, मुफ्त मेमोरी इत्यादि) कर सकता है । यहां तक कि जब एक डिस्ट्रक्टर निर्दिष्ट किया जाता है, तब भी प्रोग्राम को प्रक्रिया स्तर पर थ्रेड-विशिष्ट डेटा को मुक्त करने के लिए<code>pthread_key_delete</code> को कॉल करना होगा (डिस्ट्रक्टर केवल थ्रेड के लिए स्थानीय डेटा को मुक्त करता है)।


== भाषा-विशिष्ट कार्यान्वयन ==
== भाषा-विशिष्ट कार्यान्वयन ==
उपयुक्त एपीआई कार्यों को कॉल करने के लिए प्रोग्रामर पर भरोसा करने के अलावा, थ्रेड लोकल स्टोरेज (टीएलएस) का समर्थन करने के लिए प्रोग्रामिंग भाषा का विस्तार करना भी संभव है।
उपयुक्त एपीआई कार्यों को कॉल करने के लिए प्रोग्रामर पर विश्वाश करने के अतिरिक्त , थ्रेड लोकल स्टोरेज (टीएलएस) का समर्थन करने के लिए प्रोग्रामिंग लैंग्वेज का विस्तार करना भी संभव है।


=== सी और सी ++ ===
=== C और C++ ===
C11 (C मानक संशोधन) में, कीवर्ड <code>_Thread_local</code> थ्रेड-लोकल वेरिएबल्स को परिभाषित करने के लिए उपयोग किया जाता है। शीर्षलेख <code><threads.h></code>, यदि समर्थित है, परिभाषित करता है <code>thread_local</code> उस कीवर्ड के पर्याय के रूप में। उदाहरण उपयोग:
C11 में, कीवर्ड _<code>_Thread_local</code> का उपयोग थ्रेड-लोकल वेरिएबल्स को परिभाषित करने के लिए किया जाता है। हेडर <code><threads.h></code>, यदि समर्थित है, तो<code>thread_local</code>को उस कीवर्ड के पर्यायवाची के रूप में परिभाषित करता है। उदाहरण उपयोग:


<syntaxhighlight lang="c">
<syntaxhighlight lang="c">
Line 34: Line 34:
thread_local int foo = 0;
thread_local int foo = 0;
</syntaxhighlight>
</syntaxhighlight>
[[सी ++ 11]] पेश करता है <code>thread_local</code><ref>Section 3.7.2 in C++11 standard</ref> कीवर्ड जिसका उपयोग निम्नलिखित मामलों में किया जा सकता है
[[सी ++ 11|C++11]] <code>thread_local</code><ref>Section 3.7.2 in C++11 standard</ref> कीवर्ड प्रस्तुत करता है जिसका उपयोग निम्नलिखित स्थितियों में किया जा सकता है
* नामस्थान स्तर (वैश्विक) चर
* नामस्थान स्तर (वैश्विक) वेरिएबल
* फ़ाइल स्थिर चर
* फ़ाइल स्थिर वेरिएबल
* कार्य स्थिर चर
* कार्य स्थिर वेरिएबल
* स्थिर सदस्य चर
* स्थिर सदस्य वेरिएबल


इसके अलावा, विभिन्न संकलक कार्यान्वयन थ्रेड-स्थानीय चर घोषित करने के विशिष्ट तरीके प्रदान करते हैं:
इसके अतिरिक्त, विभिन्न संकलक कार्यान्वयन थ्रेड-स्थानीय वेरिएबल  घोषित करने के विशिष्ट विधि  प्रदान करते हैं:
*[[ओरेकल सोलारिस स्टूडियो]] सी/सी++, आईबीएम एक्सएल सी/सी++,<ref>IBM XL C/C++: [http://www-01.ibm.com/support/docview.wss?uid=swg27007322&aid=1#6 Thread-local storage]</ref> [[जीएनयू संकलक संग्रह]],<ref>GCC 3.3.1: [https://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html#Thread-Local Thread-Local Storage]</ref> [[बजना]]<ref>Clang 2.0: [http://llvm.org/releases/2.0/docs/ReleaseNotes.html release notes]</ref> और [[इंटेल सी ++ कंपाइलर]] (लिनक्स सिस्टम)<ref>Intel C++ Compiler 8.1 (linux) release notes: [http://download.intel.com/support/performancetools/c/linux/sb/clin81_relnotes.pdf#4 Thread-local Storage]</ref> सिंटैक्स का उपयोग करें:
*[[ओरेकल सोलारिस स्टूडियो]] C/C++ आईबीएम XL C/C++,<ref>IBM XL C/C++: [http://www-01.ibm.com/support/docview.wss?uid=swg27007322&aid=1#6 Thread-local storage]</ref> [[जीएनयू संकलक संग्रह]],<ref>GCC 3.3.1: [https://gcc.gnu.org/onlinedocs/gcc-3.3.1/gcc/Thread-Local.html#Thread-Local Thread-Local Storage]</ref> [[बजना]]<ref>Clang 2.0: [http://llvm.org/releases/2.0/docs/ReleaseNotes.html release notes]</ref> और [[इंटेल सी ++ कंपाइलर|इंटेल C++  कंपाइलर]] (लिनक्स सिस्टम)<ref>Intel C++ Compiler 8.1 (linux) release notes: [http://download.intel.com/support/performancetools/c/linux/sb/clin81_relnotes.pdf#4 Thread-local Storage]</ref> सिंटैक्स का उपयोग करें:
*: <code>__thread int number;</code>
*: <code>__thread int number;</code>
*[[ विजुअल सी ++ ]],<ref name="msvs-tls">Visual Studio 2003: {{cite web|url=https://docs.microsoft.com/en-us/previous-versions/6yh4a9k1(v=vs.140)|title=Thread Local Storage (TLS)|website=[[Microsoft Docs]]}}</ref> इंटेल सी/सी++ (विंडोज़ सिस्टम),<ref>Intel C++ Compiler 10.0 (windows): [http://software.intel.com/sites/default/files/m/2/4/8/5/d/16949-347599.pdf#155 Thread-local storage]</ref> [[सी ++ बिल्डर]], और डिजिटल मंगल सी ++ सिंटैक्स का उपयोग करते हैं:
*[[ विजुअल सी ++ | विजुअल C++]] ,<ref name="msvs-tls">Visual Studio 2003: {{cite web|url=https://docs.microsoft.com/en-us/previous-versions/6yh4a9k1(v=vs.140)|title=Thread Local Storage (TLS)|website=[[Microsoft Docs]]}}</ref> इंटेल C/C++ (विंडोज़ सिस्टम),<ref>Intel C++ Compiler 10.0 (windows): [http://software.intel.com/sites/default/files/m/2/4/8/5/d/16949-347599.pdf#155 Thread-local storage]</ref> [[सी ++ बिल्डर|C++  बिल्डर]], और डिजिटल मार्स C++ सिंटैक्स का उपयोग करते हैं:
*: <code>__declspec(thread) int number;</code>
*: <code>__declspec(thread) int number;</code>
*C++बिल्डर सिंटैक्स का भी समर्थन करता है:
*C++बिल्डर सिंटैक्स का भी समर्थन करता है:
*: <code>int __thread number;</code>
*: <code>int __thread number;</code>
Vista और Server 2008 से पहले के Windows संस्करणों पर, <code>__declspec(thread)</code> DLL में तभी काम करता है जब वे DLL निष्पादन योग्य के लिए बाध्य होते हैं, और LoadLibrary() (एक सुरक्षा दोष या डेटा भ्रष्टाचार हो सकता है) के साथ लोड किए गए लोगों के लिए काम नहीं करेगा।<ref name="msvs-tls" />




विस्टा और सर्वर 2008 से पहले के विंडोज़ संस्करणों पर, <code>__declspec(thread)</code> DLL में तभी काम करता है जब वे DLL निष्पादन योग्य से बंधे होते हैं, और LoadLibrary() से लोड किए गए लोगों के लिए काम नहीं करेंगे (सुरक्षा दोष या डेटा करप्शन हो सकता है)।<ref name="msvs-tls" />
=== [[सामान्य लिस्प]] (और शायद अन्य बोलियाँ) ===
=== [[सामान्य लिस्प]] (और शायद अन्य बोलियाँ) ===
कॉमन लिस्प स्कोप (कंप्यूटर साइंस) # डायनेमिक स्कोपिंग वेरिएबल्स नामक सुविधा प्रदान करता है।
कॉमन लिस्प स्कोप (कंप्यूटर साइंस) या डायनेमिक स्कोपिंग वेरिएबल्स नामक सुविधा प्रदान करता है।


डायनेमिक चर में एक बंधन होता है जो किसी फ़ंक्शन के आह्वान और उस फ़ंक्शन द्वारा बुलाए गए सभी बच्चों के लिए निजी होता है।
डायनेमिक वेरिएबल  में एक बंधन होता है जो किसी फ़ंक्शन के आह्वान और उस फ़ंक्शन द्वारा बुलाए गए सभी चिल्ड्रन के लिए निजी होता है।


यह अमूर्तता स्वाभाविक रूप से थ्रेड-विशिष्ट स्टोरेज के लिए मैप करती है, और थ्रेड्स प्रदान करने वाले लिस्प कार्यान्वयन ऐसा करते हैं। सामान्य लिस्प में कई मानक गतिशील चर होते हैं, और इसलिए धागे को भाषा के कार्यान्वयन में समझदारी से नहीं जोड़ा जा सकता है, इन चरों के बिना गतिशील बंधन में थ्रेड-स्थानीय शब्दार्थ हैं।
यह अमूर्तता स्वाभाविक रूप से थ्रेड-विशिष्ट स्टोरेज के लिए मैप करती है, और थ्रेड्स प्रदान करने वाले लिस्प कार्यान्वयन ऐसा करते हैं। सामान्य लिस्प में कई मानक गतिशील वेरिएबल  होते हैं, और इसलिए धागे को लैंग्वेज के कार्यान्वयन में समझदारी से नहीं जोड़ा जा सकता है, इन वेरिएबल के बिना गतिशील बंधन में थ्रेड-स्थानीय शब्दार्थ हैं।


उदाहरण के लिए मानक चर <code>*print-base*</code> डिफ़ॉल्ट रेडिक्स निर्धारित करता है जिसमें पूर्णांक मुद्रित होते हैं। यदि यह चर ओवरराइड किया गया है, तो सभी संलग्न कोड एक वैकल्पिक रेडिक्स में पूर्णांक प्रिंट करेंगे:
उदाहरण के लिए मानक वेरिएबल  <code>*print-base*</code> डिफ़ॉल्ट रेडिक्स निर्धारित करता है जिसमें पूर्णांक मुद्रित होते हैं। यदि यह वेरिएबल  ओवरराइड किया गया है, तो सभी संलग्न कोड एक वैकल्पिक रेडिक्स में पूर्णांक प्रिंट करेंगे:


<syntaxhighlight lang="lisp">;;; function foo and its children will print
<syntaxhighlight lang="lisp">;;; function foo and its children will print
Line 64: Line 64:
यदि फ़ंक्शंस अलग-अलग थ्रेड्स पर समवर्ती रूप से निष्पादित हो सकते हैं, तो यह बाइंडिंग उचित रूप से थ्रेड-लोकल होनी चाहिए, अन्यथा प्रत्येक थ्रेड इस बात से लड़ेगा कि ग्लोबल प्रिंटिंग रेडिक्स को कौन नियंत्रित करता है।
यदि फ़ंक्शंस अलग-अलग थ्रेड्स पर समवर्ती रूप से निष्पादित हो सकते हैं, तो यह बाइंडिंग उचित रूप से थ्रेड-लोकल होनी चाहिए, अन्यथा प्रत्येक थ्रेड इस बात से लड़ेगा कि ग्लोबल प्रिंटिंग रेडिक्स को कौन नियंत्रित करता है।


=== डी ===
=== D ===
[[डी (प्रोग्रामिंग भाषा)]] संस्करण 2 में, सभी स्थिर और वैश्विक चर डिफ़ॉल्ट रूप से थ्रेड-लोकल हैं और अन्य भाषाओं में सामान्य वैश्विक और स्थिर चर के समान सिंटैक्स के साथ घोषित किए जाते हैं। साझा किए गए कीवर्ड का उपयोग करके वैश्विक चर का स्पष्ट रूप से अनुरोध किया जाना चाहिए:
[[डी (प्रोग्रामिंग भाषा)|D (प्रोग्रामिंग भाषा)]] संस्करण 2 में, सभी स्थिर और ग्लोबल  वेरिएबल  डिफ़ॉल्ट रूप से थ्रेड-लोकल हैं और अन्य लैंग्वेज में सामान्य ग्लोबल  और स्थिर वेरिएबल  के समान सिंटैक्स के साथ घोषित किए जाते हैं। साझा किए गए कीवर्ड का उपयोग करके ग्लोबल  वेरिएबल  का स्पष्ट रूप से अनुरोध किया जाना चाहिए:


<syntaxhighlight lang = "D">
<syntaxhighlight lang = "D">
Line 71: Line 71:
shared int global;  // This is a global variable shared with all threads.
shared int global;  // This is a global variable shared with all threads.
</syntaxhighlight>
</syntaxhighlight>
साझा किया गया कीवर्ड स्टोरेज क्लास और [[ क्वालीफायर टाइप करें |क्वालीफायर टाइप करें]] दोनों के रूप में काम करता है - साझा चर कुछ प्रतिबंधों के अधीन हैं जो डेटा अखंडता को स्थिर रूप से लागू करते हैं।<ref>{{cite book | url=http://www.informit.com/articles/article.aspx?p=1609144&seqNum=3 | title=Chapter 13 - Concurrency | publisher=InformIT | website=The D Programming Language | date=6 July 2010 | access-date=3 January 2014 | author=Alexandrescu, Andrei | pages=3}}</ref> इन प्रतिबंधों के बिना क्लासिक वैश्विक चर घोषित करने के लिए, असुरक्षित __gshared कीवर्ड का उपयोग किया जाना चाहिए:<ref>{{cite web | url=http://dlang.org/migrate-to-shared.html | title=साझा करने के लिए माइग्रेट करना| website=dlang.org | date=12 May 2009 | access-date=3 January 2014 | author=Bright, Walter}}</ref>
साझा किया गया कीवर्ड स्टोरेज क्लास और [[ क्वालीफायर टाइप करें |क्वालीफायर टाइप करें]] दोनों के रूप में काम करता है - साझा वेरिएबल  कुछ प्रतिबंधों के अधीन हैं जो डेटा अखंडता को स्थिर रूप से प्रयुक्त करते हैं।<ref>{{cite book | url=http://www.informit.com/articles/article.aspx?p=1609144&seqNum=3 | title=Chapter 13 - Concurrency | publisher=InformIT | website=The D Programming Language | date=6 July 2010 | access-date=3 January 2014 | author=Alexandrescu, Andrei | pages=3}}</ref> इन प्रतिबंधों के बिना क्लासिक ग्लोबल  वेरिएबल  घोषित करने के लिए, असुरक्षित __gshared कीवर्ड का उपयोग किया जाना चाहिए:<ref>{{cite web | url=http://dlang.org/migrate-to-shared.html | title=साझा करने के लिए माइग्रेट करना| website=dlang.org | date=12 May 2009 | access-date=3 January 2014 | author=Bright, Walter}}</ref>


<syntaxhighlight lang = "D">
<syntaxhighlight lang = "D">
Line 79: Line 79:


=== जावा ===
=== जावा ===
[[ जावा (प्रोग्रामिंग भाषा) | जावा (प्रोग्रामिंग भाषा)]] में, थ्रेड-लोकल वेरिएबल्स किसके द्वारा लागू किए जाते हैं {{Javadoc:SE|java/lang|ThreadLocal}} वर्ग (कंप्यूटर विज्ञान) वस्तु। थ्रेडलोकल टाइप टी का वेरिएबल रखता है, जिसे प्राप्त/सेट विधियों के माध्यम से एक्सेस किया जा सकता है। उदाहरण के लिए, थ्रेडलोकल वैरिएबल होल्डिंग इंटीजर वैल्यू इस तरह दिखता है:
जावा में, थ्रेड-लोकल वेरिएबल्स को थ्रेडलोकल क्लास ऑब्जेक्ट द्वारा कार्यान्वित किया जाता है।  {{Javadoc:SE|java/lang|ThreadLocal}}में T प्रकार का वेरिएबल है, जिसे गेट/सेट विधियों के माध्यम से एक्सेस किया जा सकता है। उदाहरण के लिए, थ्रेडलोकल वैरिएबल होल्डिंग इंटीजर मान इस तरह दिखता है:
<syntaxhighlight lang="java">
<syntaxhighlight lang="java">
private static final ThreadLocal<Integer> myThreadLocalInteger = new ThreadLocal<Integer>();
private static final ThreadLocal<Integer> myThreadLocalInteger = new ThreadLocal<Integer>();
</syntaxhighlight>
</syntaxhighlight>
कम से कम ओरेकल/ओपनजेडीके के लिए, जावा थ्रेडिंग के अन्य पहलुओं के लिए ओएस थ्रेड का उपयोग किए जाने के बावजूद यह देशी थ्रेड-लोकल स्टोरेज का उपयोग नहीं करता है। इसके बजाए, प्रत्येक थ्रेड ऑब्जेक्ट थ्रेडलोकल ऑब्जेक्ट्स के एक (गैर-थ्रेड-सुरक्षित) मानचित्र को उनके मानों में संग्रहीत करता है (जैसा कि प्रत्येक थ्रेडलोकल के विपरीत थ्रेड ऑब्जेक्ट्स का मानचित्र मानों के लिए होता है और प्रदर्शन ओवरहेड होता है)।<ref>{{cite web|title=How is Java's ThreadLocal implemented under the hood?|url=https://stackoverflow.com/questions/1202444/how-is-javas-threadlocal-implemented-under-the-hood|website=Stack Overflow|publisher=Stack Exchange|access-date=27 December 2015}}</ref>
कम से कम ओरेकल/ओपनजेडीके के लिए, जावा थ्रेडिंग के अन्य पहलुओं के लिए ओएस थ्रेड का उपयोग किए जाने के अतिरिक्त  यह देशी थ्रेड-लोकल स्टोरेज का उपयोग नहीं करता है। इसके अतिरिक्त , प्रत्येक थ्रेड ऑब्जेक्ट थ्रेडलोकल ऑब्जेक्ट्स के एक (गैर-थ्रेड-सुरक्षित) मानचित्र को उनके मानों में संग्रहीत करता है (जैसा कि प्रत्येक थ्रेडलोकल के विपरीत थ्रेड ऑब्जेक्ट्स का मानचित्र मानों के लिए होता है और प्रदर्शन ओवरहेड होता है)।<ref>{{cite web|title=How is Java's ThreadLocal implemented under the hood?|url=https://stackoverflow.com/questions/1202444/how-is-javas-threadlocal-implemented-under-the-hood|website=Stack Overflow|publisher=Stack Exchange|access-date=27 December 2015}}</ref>




===.NET भाषाएँ: C# और अन्य ===
===.NET लैंग्वेज : C# और अन्य ===
सी शार्प (प्रोग्रामिंग भाषा)|सी# जैसी .NET फ्रेमवर्क भाषाओं में, स्थिर क्षेत्रों को [https://docs.microsoft.com/en-us/dotnet/api/system.threadstaticattribute थ्रेडस्टैटिक विशेषता] के साथ चिह्नित किया जा सकता है:
C# जैसी .NET फ्रेमवर्क भाषाओं में, स्थिर फ़ील्ड को थ्रेडस्टैटिक विशेषता के साथ चिह्नित किया जा सकता है


<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
Line 97: Line 97:
</syntaxhighlight>
</syntaxhighlight>
.NET Framework 4.0 में [https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadlocal-1 System.Threading.ThreadLocal<T>] वर्ग थ्रेड आवंटित करने और आलसी लोड करने के लिए उपलब्ध है -स्थानीय चर।
.NET Framework 4.0 में [https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadlocal-1 System.Threading.ThreadLocal<T>] वर्ग थ्रेड आवंटित करने और आलसी लोड करने के लिए उपलब्ध है -स्थानीय चर।
.NET फ्रेमवर्क 4.0 में [https://docs.microsoft.com/en-us/dotnet/api/system.threading.threadlocal-1 System.Threading.ThreadLocal<T>]  क्लास थ्रेड-लोकल वेरिएबल्स को आवंटित करने और आसानी से लोड करने के लिए उपलब्ध है।
<syntaxhighlight lang="csharp">
<syntaxhighlight lang="csharp">
class FooBar
class FooBar
Line 103: Line 105:
}
}
</syntaxhighlight>
</syntaxhighlight>
इसके अलावा [https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.getnameddataslot a API] गतिशील रूप से थ्रेड-स्थानीय चर आवंटित करने के लिए उपलब्ध है।
इसके अतिरिक्त [https://learn.microsoft.com/en-us/dotnet/api/system.threading.thread.getnameddataslot a API] गतिशील रूप से थ्रेड-स्थानीय वेरिएबल आवंटित करने के लिए उपलब्ध है।


=== [[वस्तु पास्कल]] ===
=== [[वस्तु पास्कल]] ===
ऑब्जेक्ट पास्कल ([[ डेल्फी (प्रोग्रामिंग भाषा) ]]) या [[ फ़्री पास्कल |फ़्री पास्कल]] में थ्रेड-लोकल स्टोरेज का उपयोग करके चर घोषित करने के लिए 'var' के बजाय थ्रेडवार आरक्षित कीवर्ड का उपयोग किया जा सकता है।
ऑब्जेक्ट पास्कल ([[ डेल्फी (प्रोग्रामिंग भाषा) ]]) या [[ फ़्री पास्कल |फ़्री पास्कल]] में थ्रेड-लोकल स्टोरेज का उपयोग करके वेरिएबल  घोषित करने के लिए 'var' के अतिरिक्त थ्रेडवार आरक्षित कीवर्ड का उपयोग किया जा सकता है।
<syntaxhighlight lang="pascal">
<syntaxhighlight lang="pascal">
var
var
Line 115: Line 117:




=== उद्देश्य-सी ===
=== उद्देश्य-c ===
[[कोको (एपीआई)]], [[जीएनयूस्टेप]] और [[ओपनस्टेप]] में, प्रत्येक <code>NSThread</code> ऑब्जेक्ट में थ्रेड-लोकल डिक्शनरी है जिसे थ्रेड के माध्यम से एक्सेस किया जा सकता है <code>threadDictionary</code> तरीका।
कोको, जीएनयूस्टेप और ओपनस्टेप में, प्रत्येक <code>NSThread</code>ऑब्जेक्ट में एक थ्रेड-लोकल डिक्शनरी होती है जिसे थ्रेड की <code>threadDictionary</code> विधि के माध्यम से एक्सेस किया जा सकता है।
<syntaxhighlight lang="objc">
<syntaxhighlight lang="objc">
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
Line 124: Line 126:


=== [[पर्ल]] ===
=== [[पर्ल]] ===
[[व्यापक पर्ल आर्काइव नेटवर्क]] (सीपीएएन) पर मौजूदा कोड का एक बड़ा हिस्सा पहले से ही मौजूद होने के बाद, भाषा के विकास में पर्ल थ्रेड्स को देर से जोड़ा गया था। इस प्रकार, डिफ़ॉल्ट रूप से पर्ल में थ्रेड्स मौजूदा गैर-थ्रेड-जागरूक कोड पर थ्रेड्स के प्रभाव को कम करने के लिए, सभी वेरिएबल्स के लिए अपना स्थानीय स्टोरेज लेते हैं। पर्ल में, एक विशेषता का उपयोग करके एक थ्रेड-साझा चर बनाया जा सकता है:
[[व्यापक पर्ल आर्काइव नेटवर्क]] (सीपीएएन) पर उपस्थित कोड का एक बड़ा भाग पहले से ही उपस्थित होने के बाद लैंग्वेज के विकास में पर्ल थ्रेड्स को देर से जोड़ा गया था। इस प्रकार, डिफ़ॉल्ट रूप से पर्ल में थ्रेड्स उपस्थित गैर-थ्रेड-जागरूक कोड पर थ्रेड्स के प्रभाव को कम करने के लिए, सभी वेरिएबल्स के लिए अपना स्थानीय स्टोरेज लेते हैं। पर्ल में, एक विशेषता का उपयोग करके एक थ्रेड-साझा वेरिएबल  बनाया जा सकता है:
<syntaxhighlight lang="perl">
<syntaxhighlight lang="perl">
use threads;
use threads;
Line 151: Line 153:


=== रूबी ===
=== रूबी ===
[[ रूबी (प्रोग्रामिंग भाषा) | रूबी (प्रोग्रामिंग भाषा)]] []=/[] विधियों का उपयोग करके थ्रेड-स्थानीय चर बना/एक्सेस कर सकती है:
[[ रूबी (प्रोग्रामिंग भाषा) | रूबी (प्रोग्रामिंग भाषा)]] []=/[] विधियों का उपयोग करके थ्रेड-स्थानीय वेरिएबल  बना/एक्सेस कर सकती है:


<syntaxhighlight lang="ruby">
<syntaxhighlight lang="ruby">
Line 158: Line 160:




=== जंग ===
=== रस्ट ===


थ्रेड-लोकल वेरिएबल्स को [[ जंग (प्रोग्रामिंग भाषा) |जंग (प्रोग्रामिंग भाषा)]] का उपयोग करके बनाया जा सकता है {{code | thread_local!}} रस्ट मानक पुस्तकालय द्वारा प्रदान किया गया मैक्रो:
थ्रेड_लोकल का उपयोग करके रस्ट में {{code | thread_local!}} वैरिएबल बनाए जा सकते हैं! रस्ट मानक पुस्तकालय द्वारा प्रदान किया गया मैक्रो:


<syntaxhighlight lang="rust">
<syntaxhighlight lang="rust">
Line 192: Line 194:


== यह भी देखें ==
== यह भी देखें ==
* [[OpenMP]] समानांतर प्रोसेसर कुछ हार्डवेयर के लिए समर्थन करता है
* [[OpenMP|ओपनएमपी]] समानांतर प्रोसेसर कुछ हार्डवेयर के लिए समर्थन करता है
* साझा मेमोरी स्मृति पृष्ठों तक पहुंच और कॉन्फ़िगरेशन (सीपीयू और या कर्नेल समर्थित, यदि समर्थित हो)
* साझा मेमोरी मेमोरी  पृष्ठों तक पहुंच और कॉन्फ़िगरेशन (सीपीयू और या कर्नेल समर्थित, यदि समर्थित हो)
* [[संदर्भ स्विच]] को टास्क स्विचिंग भी कहा जाता है, थ्रेड्स, पेज हार्डवेयर त्वरित और या कर्नेल प्रदान किए जाते हैं
* [[संदर्भ स्विच]] को टास्क स्विचिंग भी कहा जाता है, थ्रेड्स, पेज हार्डवेयर त्वरित और या कर्नेल प्रदान किए जाते हैं
* [[सेमाफोर (प्रोग्रामिंग)]] LOCK, अगर (सीपीयू) मल्टी-पोर्टेड मेमोरी को पर्याप्त रूप से सपोर्ट नहीं करता है (सीपीयू फ्रीज को रोकें)
* [[सेमाफोर (प्रोग्रामिंग)]] लॉक, यदि (सीपीयू) मल्टी-पोर्टेड मेमोरी को पर्याप्त रूप से सपोर्ट नहीं करता है (सीपीयू फ्रीज को रोकें)


==संदर्भ==
==संदर्भ==

Revision as of 11:26, 29 July 2023


कंप्यूटर प्रोग्रामिंग में, थ्रेड-लोकल स्टोरेज (TLS) एक मेमोरी मैनेजमेंट मेथड है जो स्थैतिक मेमोरी आवंटन या ग्लोबल कंप्यूटर स्टोरेज को थ्रेड (कंप्यूटिंग) के लिए लोकल का उपयोग करता है।

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

कई प्रणालियाँ थ्रेड-लोकल मेमोरी ब्लॉक के आकार पर प्रतिबंध लगाती हैं, वास्तव में अधिकांशतः किंतु तंग सीमाएँ दूसरी ओर, यदि कोई सिस्टम कम से कम एक मेमोरी एड्रेस (पॉइंटर) आकार का वेरिएबल थ्रेड-लोकल प्रदान कर सकता है, तो यह इच्छित रूप से आकार के मेमोरी ब्लॉक को थ्रेड-लोकल विधि से उपयोग करने की अनुमति देता है, इस तरह के मेमोरी ब्लॉक को गतिशील रूप से आवंटित करके और स्टोर करके थ्रेड-लोकल वैरिएबल में उस ब्लॉक का मेमोरी एड्रेस कम निर्देश सेट कंप्यूटर मशीनों पर, कॉलिंग कन्वेंशन अधिकांशतः इस उपयोग के लिए थ्रेड पॉइंटर रजिस्टर आरक्षित करता है।

विंडोज कार्यान्वयन

एप्लिकेशन प्रोग्रामिंग इंटरफ़ेस (एपीआई) फ़ंक्शन TlsAlloc का उपयोग अप्रयुक्त टीएलएस स्लॉट इंडेक्स प्राप्त करने के लिए किया जा सकता है; टीएलएस स्लॉट इंडेक्स को तब 'प्रयुक्त' माना जाएगा।

TlsGetValue और TlsSetValue फ़ंक्शंस का उपयोग टीएलएस स्लॉट इंडेक्स द्वारा पहचाने गए थ्रेड-लोकल वेरिएबल में मेमोरी एड्रेस को पढ़ने और लिखने के लिए किया जाता है। TlsSetValue केवल वर्तमान थ्रेड के वेरिएबल को प्रभावित करता है। टीएलएस स्लॉट इंडेक्स जारी करने के लिए TlsFree फ़ंक्शन को कॉल किया जा सकता है।

प्रत्येक थ्रेड के लिए एक विन32 थ्रेड सूचना ब्लॉक है। इस ब्लॉक में प्रविष्टियों में से एक उस थ्रेड के लिए थ्रेड-लोकल स्टोरेज टेबल है।[1] TlsAlloc प्रत्येक कॉल के लिए इस तालिका में एक अनुक्रमणिका लौटाता है, अद्वितीय प्रति एड्रेस स्थान प्रत्येक थ्रेड के पास थ्रेड-लोकल स्टोरेज टेबल की अपनी कॉपी होती है। इसलिए, प्रत्येक थ्रेड स्वतंत्र रूप से TlsSetValue(index) का उपयोग कर सकता है और TlsGetValue(index) के माध्यम से निर्दिष्ट मान प्राप्त कर सकता है, क्योंकि ये थ्रेड की अपनी तालिका में एक प्रविष्टि सेट और खोजते हैं।

TlsXxx ​​फ़ंक्शन वर्ग के अतिरिक्त, विंडोज़ एक्जीक्यूटेबल्स एक सेक्शन को परिभाषित कर सकते हैं जो निष्पादन प्रक्रिया के प्रत्येक थ्रेड के लिए एक अलग पृष्ठ पर मैप किया गया है। TlsXxx ​​मानों के विपरीत, इन पृष्ठों में इच्छित और वैध पते हो सकते हैं। चूँकि ये पते प्रत्येक निष्पादन थ्रेड के लिए अलग-अलग हैं और इसलिए एसिंक्रोनस फ़ंक्शंस (जो एक अलग थ्रेड में निष्पादित हो सकते हैं) या अन्यथा कोड को पास नहीं किया जाना चाहिए, जो मानते हैं कि पूरी प्रक्रिया के अंदर एक वर्चुअल एड्रेस अद्वितीय है। टीएलएस अनुभागों को पेजिंग का उपयोग करके प्रबंधित किया जाता है और इसका आकार पृष्ठ आकार (x86 मशीनों पर 4kB) तक निर्धारित किया जाता है। इस तरह के अनुभागों को केवल एक प्रोग्राम के मुख्य निष्पादन योग्य के अंदर परिभाषित किया जा सकता है - डायनामिक-लिंक लाइब्रेरी में ऐसे अनुभाग नहीं होने चाहिए, क्योंकि लोड लाइब्रेरी के साथ लोड करते समय उन्हें सही रूप से प्रारंभ नहीं किया जाता है।

पीथ्रेड्स कार्यान्वयन

Pthreads API में, थ्रेड के लिए स्थानीय मेमोरी को थ्रेड-विशिष्ट डेटा शब्द के साथ नामित किया गया है।

थ्रेड-विशिष्ट डेटा के लिए कुंजी बनाने और हटाने के लिए क्रमशः pthread_key_create and pthread_key_delete फ़ंक्शन का उपयोग किया जाता है। कुंजी का प्रकार स्पष्ट रूप से अपारदर्शी छोड़ दिया गया है और इसे pthread_key_tकहा जाता है। इस कुंजी को सभी थ्रेड्स द्वारा देखा जा सकता है। प्रत्येक थ्रेड में, कुंजी को pthread_setspecific के माध्यम से थ्रेड-विशिष्ट डेटा से जोड़ा जा सकता है। डेटा को बाद में pthread_getspecific. का उपयोग करके पुनर्प्राप्त किया जा सकता है।

इसके अतिरिक्त pthread_key_create वैकल्पिक रूप से एक डिस्ट्रक्टर फ़ंक्शन को स्वीकार कर सकता है जिसे थ्रेड-विशिष्ट डेटा NULL नहीं होने पर थ्रेड निकास पर स्वचालित रूप से कॉल किया जाएगा। विध्वंसक कुंजी से जुड़े मान को पैरामीटर के रूप में प्राप्त करता है जिससे वह सफाई क्रियाएं (संवर्त कनेक्शन, मुफ्त मेमोरी इत्यादि) कर सकता है । यहां तक कि जब एक डिस्ट्रक्टर निर्दिष्ट किया जाता है, तब भी प्रोग्राम को प्रक्रिया स्तर पर थ्रेड-विशिष्ट डेटा को मुक्त करने के लिएpthread_key_delete को कॉल करना होगा (डिस्ट्रक्टर केवल थ्रेड के लिए स्थानीय डेटा को मुक्त करता है)।

भाषा-विशिष्ट कार्यान्वयन

उपयुक्त एपीआई कार्यों को कॉल करने के लिए प्रोग्रामर पर विश्वाश करने के अतिरिक्त , थ्रेड लोकल स्टोरेज (टीएलएस) का समर्थन करने के लिए प्रोग्रामिंग लैंग्वेज का विस्तार करना भी संभव है।

C और C++

C11 में, कीवर्ड __Thread_local का उपयोग थ्रेड-लोकल वेरिएबल्स को परिभाषित करने के लिए किया जाता है। हेडर <threads.h>, यदि समर्थित है, तोthread_localको उस कीवर्ड के पर्यायवाची के रूप में परिभाषित करता है। उदाहरण उपयोग:

#include <threads.h>
thread_local int foo = 0;

C++11 thread_local[2] कीवर्ड प्रस्तुत करता है जिसका उपयोग निम्नलिखित स्थितियों में किया जा सकता है

  • नामस्थान स्तर (वैश्विक) वेरिएबल
  • फ़ाइल स्थिर वेरिएबल
  • कार्य स्थिर वेरिएबल
  • स्थिर सदस्य वेरिएबल

इसके अतिरिक्त, विभिन्न संकलक कार्यान्वयन थ्रेड-स्थानीय वेरिएबल घोषित करने के विशिष्ट विधि प्रदान करते हैं:


विस्टा और सर्वर 2008 से पहले के विंडोज़ संस्करणों पर, __declspec(thread) DLL में तभी काम करता है जब वे DLL निष्पादन योग्य से बंधे होते हैं, और LoadLibrary() से लोड किए गए लोगों के लिए काम नहीं करेंगे (सुरक्षा दोष या डेटा करप्शन हो सकता है)।[7]

सामान्य लिस्प (और शायद अन्य बोलियाँ)

कॉमन लिस्प स्कोप (कंप्यूटर साइंस) या डायनेमिक स्कोपिंग वेरिएबल्स नामक सुविधा प्रदान करता है।

डायनेमिक वेरिएबल में एक बंधन होता है जो किसी फ़ंक्शन के आह्वान और उस फ़ंक्शन द्वारा बुलाए गए सभी चिल्ड्रन के लिए निजी होता है।

यह अमूर्तता स्वाभाविक रूप से थ्रेड-विशिष्ट स्टोरेज के लिए मैप करती है, और थ्रेड्स प्रदान करने वाले लिस्प कार्यान्वयन ऐसा करते हैं। सामान्य लिस्प में कई मानक गतिशील वेरिएबल होते हैं, और इसलिए धागे को लैंग्वेज के कार्यान्वयन में समझदारी से नहीं जोड़ा जा सकता है, इन वेरिएबल के बिना गतिशील बंधन में थ्रेड-स्थानीय शब्दार्थ हैं।

उदाहरण के लिए मानक वेरिएबल *print-base* डिफ़ॉल्ट रेडिक्स निर्धारित करता है जिसमें पूर्णांक मुद्रित होते हैं। यदि यह वेरिएबल ओवरराइड किया गया है, तो सभी संलग्न कोड एक वैकल्पिक रेडिक्स में पूर्णांक प्रिंट करेंगे:

;;; function foo and its children will print
;; in hexadecimal:
(let ((*print-base* 16)) (foo))

यदि फ़ंक्शंस अलग-अलग थ्रेड्स पर समवर्ती रूप से निष्पादित हो सकते हैं, तो यह बाइंडिंग उचित रूप से थ्रेड-लोकल होनी चाहिए, अन्यथा प्रत्येक थ्रेड इस बात से लड़ेगा कि ग्लोबल प्रिंटिंग रेडिक्स को कौन नियंत्रित करता है।

D

D (प्रोग्रामिंग भाषा) संस्करण 2 में, सभी स्थिर और ग्लोबल वेरिएबल डिफ़ॉल्ट रूप से थ्रेड-लोकल हैं और अन्य लैंग्वेज में सामान्य ग्लोबल और स्थिर वेरिएबल के समान सिंटैक्स के साथ घोषित किए जाते हैं। साझा किए गए कीवर्ड का उपयोग करके ग्लोबल वेरिएबल का स्पष्ट रूप से अनुरोध किया जाना चाहिए:

int threadLocal;  // This is a thread-local variable.
shared int global;  // This is a global variable shared with all threads.

साझा किया गया कीवर्ड स्टोरेज क्लास और क्वालीफायर टाइप करें दोनों के रूप में काम करता है - साझा वेरिएबल कुछ प्रतिबंधों के अधीन हैं जो डेटा अखंडता को स्थिर रूप से प्रयुक्त करते हैं।[9] इन प्रतिबंधों के बिना क्लासिक ग्लोबल वेरिएबल घोषित करने के लिए, असुरक्षित __gshared कीवर्ड का उपयोग किया जाना चाहिए:[10]

__gshared int global;  // This is a plain old global variable.


जावा

जावा में, थ्रेड-लोकल वेरिएबल्स को थ्रेडलोकल क्लास ऑब्जेक्ट द्वारा कार्यान्वित किया जाता है। ThreadLocalमें T प्रकार का वेरिएबल है, जिसे गेट/सेट विधियों के माध्यम से एक्सेस किया जा सकता है। उदाहरण के लिए, थ्रेडलोकल वैरिएबल होल्डिंग इंटीजर मान इस तरह दिखता है:

private static final ThreadLocal<Integer> myThreadLocalInteger = new ThreadLocal<Integer>();

कम से कम ओरेकल/ओपनजेडीके के लिए, जावा थ्रेडिंग के अन्य पहलुओं के लिए ओएस थ्रेड का उपयोग किए जाने के अतिरिक्त यह देशी थ्रेड-लोकल स्टोरेज का उपयोग नहीं करता है। इसके अतिरिक्त , प्रत्येक थ्रेड ऑब्जेक्ट थ्रेडलोकल ऑब्जेक्ट्स के एक (गैर-थ्रेड-सुरक्षित) मानचित्र को उनके मानों में संग्रहीत करता है (जैसा कि प्रत्येक थ्रेडलोकल के विपरीत थ्रेड ऑब्जेक्ट्स का मानचित्र मानों के लिए होता है और प्रदर्शन ओवरहेड होता है)।[11]


.NET लैंग्वेज : C# और अन्य

C# जैसी .NET फ्रेमवर्क भाषाओं में, स्थिर फ़ील्ड को थ्रेडस्टैटिक विशेषता के साथ चिह्नित किया जा सकता है

class FooBar
{
    [ThreadStatic]
    private static int _foo;
}

.NET Framework 4.0 में System.Threading.ThreadLocal<T> वर्ग थ्रेड आवंटित करने और आलसी लोड करने के लिए उपलब्ध है -स्थानीय चर।

.NET फ्रेमवर्क 4.0 में System.Threading.ThreadLocal<T> क्लास थ्रेड-लोकल वेरिएबल्स को आवंटित करने और आसानी से लोड करने के लिए उपलब्ध है।

class FooBar
{
    private static System.Threading.ThreadLocal<int> _foo;
}

इसके अतिरिक्त a API गतिशील रूप से थ्रेड-स्थानीय वेरिएबल आवंटित करने के लिए उपलब्ध है।

वस्तु पास्कल

ऑब्जेक्ट पास्कल (डेल्फी (प्रोग्रामिंग भाषा) ) या फ़्री पास्कल में थ्रेड-लोकल स्टोरेज का उपयोग करके वेरिएबल घोषित करने के लिए 'var' के अतिरिक्त थ्रेडवार आरक्षित कीवर्ड का उपयोग किया जा सकता है।

var
   mydata_process: integer;
threadvar
   mydata_threadlocal: integer;


उद्देश्य-c

कोको, जीएनयूस्टेप और ओपनस्टेप में, प्रत्येक NSThreadऑब्जेक्ट में एक थ्रेड-लोकल डिक्शनरी होती है जिसे थ्रेड की threadDictionary विधि के माध्यम से एक्सेस किया जा सकता है।

NSMutableDictionary *dict = [[NSThread currentThread] threadDictionary];
dict[@"A key"] = @"Some data";


पर्ल

व्यापक पर्ल आर्काइव नेटवर्क (सीपीएएन) पर उपस्थित कोड का एक बड़ा भाग पहले से ही उपस्थित होने के बाद लैंग्वेज के विकास में पर्ल थ्रेड्स को देर से जोड़ा गया था। इस प्रकार, डिफ़ॉल्ट रूप से पर्ल में थ्रेड्स उपस्थित गैर-थ्रेड-जागरूक कोड पर थ्रेड्स के प्रभाव को कम करने के लिए, सभी वेरिएबल्स के लिए अपना स्थानीय स्टोरेज लेते हैं। पर्ल में, एक विशेषता का उपयोग करके एक थ्रेड-साझा वेरिएबल बनाया जा सकता है:

use threads;
use threads::shared;

my $localvar;
my $sharedvar :shared;


प्योरबेसिक

PureBasic में थ्रेड वेरिएबल्स कीवर्ड थ्रेडेड के साथ घोषित किए जाते हैं।

Threaded Var


पायथन

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

import threading
mydata = threading.local()
mydata.x = 1


रूबी

रूबी (प्रोग्रामिंग भाषा) []=/[] विधियों का उपयोग करके थ्रेड-स्थानीय वेरिएबल बना/एक्सेस कर सकती है:

Thread.current[:user_id] = 1


रस्ट

थ्रेड_लोकल का उपयोग करके रस्ट में thread_local! वैरिएबल बनाए जा सकते हैं! रस्ट मानक पुस्तकालय द्वारा प्रदान किया गया मैक्रो:

use std::cell::RefCell;
use std::thread;

thread_local!(static FOO: RefCell<u32> = RefCell::new(1));

FOO.with(|f| {
    assert_eq!(*f.borrow(), 1);
    *f.borrow_mut() = 2;
});

// each thread starts out with the initial value of 1, even though this thread already changed its copy of the thread local value to 2
let t = thread::spawn(move || {
    FOO.with(|f| {
        assert_eq!(*f.borrow(), 1);
        *f.borrow_mut() = 3;
    });
});

// wait for the thread to complete and bail out on panic
t.join().unwrap();

// original thread retains the original value of 2 despite the child thread changing the value to 3 for that thread
FOO.with(|f| {
    assert_eq!(*f.borrow(), 2);
});


यह भी देखें

  • ओपनएमपी समानांतर प्रोसेसर कुछ हार्डवेयर के लिए समर्थन करता है
  • साझा मेमोरी मेमोरी पृष्ठों तक पहुंच और कॉन्फ़िगरेशन (सीपीयू और या कर्नेल समर्थित, यदि समर्थित हो)
  • संदर्भ स्विच को टास्क स्विचिंग भी कहा जाता है, थ्रेड्स, पेज हार्डवेयर त्वरित और या कर्नेल प्रदान किए जाते हैं
  • सेमाफोर (प्रोग्रामिंग) लॉक, यदि (सीपीयू) मल्टी-पोर्टेड मेमोरी को पर्याप्त रूप से सपोर्ट नहीं करता है (सीपीयू फ्रीज को रोकें)

संदर्भ

  1. Pietrek, Matt (May 2006). "हुड के नीचे". MSDN. Retrieved 6 April 2010.
  2. Section 3.7.2 in C++11 standard
  3. IBM XL C/C++: Thread-local storage
  4. GCC 3.3.1: Thread-Local Storage
  5. Clang 2.0: release notes
  6. Intel C++ Compiler 8.1 (linux) release notes: Thread-local Storage
  7. 7.0 7.1 Visual Studio 2003: "Thread Local Storage (TLS)". Microsoft Docs.
  8. Intel C++ Compiler 10.0 (windows): Thread-local storage
  9. Alexandrescu, Andrei (6 July 2010). Chapter 13 - Concurrency. p. 3. Retrieved 3 January 2014. {{cite book}}: |website= ignored (help)
  10. Bright, Walter (12 May 2009). "साझा करने के लिए माइग्रेट करना". dlang.org. Retrieved 3 January 2014.
  11. "How is Java's ThreadLocal implemented under the hood?". Stack Overflow. Stack Exchange. Retrieved 27 December 2015.


बाहरी संबंध