2017-08-23 22 views
5

मैं समझने की कोशिश कर रहा हूं कि वास्तव में thread_local क्वालीफायर कैसे काम करता है और जहां वास्तविक चर संग्रहीत किया जाता है? यह सी ++ पर है।सी ++ - thread_local चर कहाँ संग्रहीत हैं?

कहें कि मेरे पास एकाधिक सदस्य चर के साथ एक कक्षा है। कक्षा का एक objet ढेर पर तत्काल है और वस्तु 2 धागे के बीच साझा किया जाता है। उचित लॉकिंग तंत्र का उपयोग यह सुनिश्चित करने के लिए किया जाता है कि एक ही समय में एक सदस्य चर पर दो थ्रेड नहीं हो रहे हैं।

कुछ थ्रेड विशिष्ट वस्तुओं का ट्रैक रखने के लिए धागे की आवश्यकता है। इसलिए मैं क्लास घोषणा के रूप में एक ही हेडर फ़ाइल में thread_local चर बनाने की सोच रहा हूं। जैसा कि मैं समझता हूं, दोनों धागे को इस चर की अपनी प्रति प्राप्त होगी, सही? स्मृति में संग्रहीत धागा स्थानीय चर कहाँ है? यदि डेटा सेगमेंट, निष्पादन के दौरान सही चर कैसे उठाया जाता है?

+4

मुझे लगता है कि यह कार्यान्वयन परिभाषित किया गया है। – drescherjm

+2

जहां _any_ चर संग्रहित हैं, यह कार्यान्वयन विशिष्ट है। –

+3

आम कार्यान्वयन क्या करते हैं? जीसीसी कहो। आम तौर पर, हम ढेर पर होने के लिए ढेर, स्थानीय चर और फ़ंक्शन तर्कों पर होने के लिए मॉलोक/नए का उपयोग करके गतिशील आवंटन पर विचार कर सकते हैं। अधिकांश कार्यान्वयन इस से चिपके रहते हैं। इस संदर्भ को देखते हुए, thread_local चर कहाँ जाते हैं? –

उत्तर

2

1. मैं समझता हूँ के रूप में, दोनों धागे इस चर की अपनी कॉपी को मिल जाएगा, सही है?
हां। प्रत्येक थ्रेड को thread_local चर की अपनी प्रति प्राप्त होती है।
2. स्मृति में संग्रहीत थ्रेड स्थानीय चर कहाँ है? यदि डेटा सेगमेंट, निष्पादन के दौरान सही चर कैसे उठाया जाता है?
थ्रेड_लोकल थ्रेड स्थानीय संग्रहण अवधारणा का कार्यान्वयन है। टीएलएस को प्रत्येक थ्रेड ऑब्जेक्ट के साथ स्लॉट की एक तालिका के रूप में कार्यान्वित किया जाता है। प्रत्येक थ्रेड में टेबल की अपनी प्रति होती है। उदाहरण के लिए टीएलएस के विंडोज कार्यान्वयन में यह तालिका थ्रेड के थ्रेड सूचना ब्लॉक के भीतर है। जब वैश्विक/स्थिर चर को thread_local के रूप में घोषित किया जाता है, तो यह उसी थ्रेड पर प्रत्येक थ्रेड के एक टेबल स्लॉट से जुड़ा होगा। जब थ्रेड_लोकल वैरिएबल को थ्रेड द्वारा एक्सेस किया जाता है तो वर्तमान थ्रेड संदर्भ का उपयोग करके, धागे की इस थ्रेड ऑब्जेक्ट के भीतर टेबल स्लॉट से जुड़े चर की अपनी प्रति एक्सेस की जाती है। टीएलएस कार्यान्वयन पर अधिक जानकारी के लिए कृपया इस लिंक को देखें। https://en.wikipedia.org/wiki/Thread-local_storage

+0

क्या डेटा वास्तविक तालिका में ही संग्रहीत है? यह अजीब लगता है, जैसे कि आपके पास अलग-अलग आकार की थ्रेड_लोकल ऑब्जेक्ट्स हैं, वहां एक सतत "स्लॉट" आकार नहीं है। यदि तालिका ऑब्जेक्ट्स को स्वयं संग्रहित नहीं करती है, बल्कि इसके बजाय ऑब्जेक्ट्स को पॉइंटर्स करती है, तो वस्तुओं को आवंटित किया जा रहा है? किसी भी मामले में, मेमोरी में टेबल को आवंटित किया जा रहा है, जैसे कि यह संभावित थ्रेड_लोकल ऑब्जेक्ट्स की व्यापक रूप से भिन्न संख्या (और आकार?) को संभाल सकता है? –

-1

आपके विवरण यह लगता है कि आप कुछ गैर स्थैतिक सदस्य var को thread_local के रूप में चिह्नित करना चाहते हैं। इसकी अनुमति नहीं है।

thread_localstatic कुछ हद तक की तरह (वैश्विक), लेकिन हर धागा जबकि static के लिए विशिष्ट सभी धागे

प्रत्येक धागा खुद स्मृति पर्वतमाला रखती भर में साझा किया जाता है। उदाहरण के लिए एक खुद का ढेर।

http://en.cppreference.com/w/cpp/language/storage_durationReferen

+1

क्षमा करें, अगर स्पष्ट नहीं है। मैं थ्रेड_क्कोल के रूप में एक वैश्विक चर (केवल वर्ग घोषणा के समान ही शीर्षलेख में घोषित करना चाहता हूं) बनाना चाहता हूं। इसके अलावा, यह वही ऑब्जेक्ट उदाहरण दोनों धागे द्वारा उपयोग किया जा रहा है। इसलिए सदस्य चर किसी भी तरह से हैं, इसलिए ताले का उपयोग करके संरक्षित। –

+2

जब सभी धागे एक ही वस्तु साझा करते हैं, तो आपको thread_local की आवश्यकता नहीं होती है। यदि कुछ धागे किसी ऑब्जेक्ट को साझा करते हैं, तो आपको उस जानकारी को थ्रेड निर्माण समय पर, उदाहरण के लिए पास करना होगा, और आपको उस ऑब्जेक्ट में थ्रेड_लोकल पॉइंटर चाहिए। –

+0

जैसा कि आपने कहा था ऑब्जेक्ट पॉइंटर पारित किया जा रहा है। उस सूचक पर कोई thread_lcoal घोषणा नहीं। कुछ सदस्य कार्यों को यह जानने की जरूरत है कि उन्हें किस धागे से बुलाया जा रहा है। इसलिए हेडर फ़ाइल में thread_local वैश्विक चर के बारे में सोच रहा है। –

2

64 बिट विंडोज के मामले में, टीएलएस, जी एस चयनकर्ता रजिस्टर के माध्यम से पहुँचा जा सकता है, धागा (CreateThread() के दौरान आवंटित) प्रति एक अलग भौतिक पता स्थान का उपयोग हालांकि विजुअल स्टूडियो एक प्रक्रिया में टीएलएस को मैप कर सकते हैं/थ्रेड वर्चुअल एड्रेस स्पेस, प्रत्येक थ्रेड के साथ एक अलग वर्चुअल एड्रेस प्राप्त होता है, क्योंकि यह प्रत्येक थ्रेड के लिए एक अलग भौतिक पता है। आप डिबगर के साथ रैंड() में कदम उठाकर अलग किए गए कोड को देख सकते हैं यह देखने के लिए कि यह बीज को कैसे एक्सेस करता है, जो एक टीएलएस चर है।

संबंधित मुद्दे