क्या धागे का एक अलग ढेर है?


114

जहां तक ​​मुझे पता है कि ऑपरेटिंग सिस्टम द्वारा थ्रेड बनाए जाने पर प्रत्येक थ्रेड को एक अलग स्टैक मिलता है। मुझे आश्चर्य है कि अगर प्रत्येक धागे में खुद के लिए भी एक ढेर है?


हाँ, विंडोज़ और लिनक्स, सी लाइब्रेरी

3
अच्छा लगा। +1 उन मूलभूत प्रश्नों को रखें।

जवाबों:


128

नहीं। सभी धागे एक साझा ढेर हैं।

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

चूँकि सभी धागे समान हील को साझा करते हैं, इसलिए आवंटनकर्ता / डीलर से एक्सेस को सिंक्रनाइज़ किया जाना चाहिए। आवंटन विवाद से बचने के लिए विभिन्न तरीके और पुस्तकालय हैं ।

कुछ भाषाएं आपको मेमोरी, या व्यक्तिगत ढेर के निजी पूल बनाने की अनुमति देती हैं, जिन्हें आप एकल थ्रेड को असाइन कर सकते हैं।


5
आमतौर पर धागे संसाधनों को साझा करते हैं, जैसे कि मेमोरी, इसलिए कोई भी गैर-ब्राइडेड थ्रेड कार्यान्वयन ढेर को साझा करेगा।
आर। मार्टिनो फर्नांडिस

10
मुख्य कारण प्रत्येक थ्रेड अपने स्वयं के ढेर है कि धागा वास्तव में कुछ (कॉल की तरह एक कार्यों) ऐसा कर सकते हैं है ...
एडमंड

3
हर धागे का एक अलग ढेर होता है, लेकिन यह जरूरी नहीं कि 'निजी' हो। अन्य थ्रेड्स को आमतौर पर इसे एक्सेस करने की अनुमति है।
zch

you will get a stack overflow.स्टैक ओवरफ्लो पर एक स्टैक ओवरफ्लो!
जॉन स्ट्रोड

2
@ क्राइसरोन प्रत्येक थ्रेड के लिए एक अलग हीप को सेट करना संभव है, लेकिन यदि आप ऐसा करते हैं, तो डिफ़ॉल्ट साझा हीप का उपयोग करने के बजाय, तो यह मुश्किल हो जाता है जैसे कि ए थ्रेड ए को बफर आवंटित करना, इसे डेटा के साथ भरना, इसे थ्रेड बी में पास करना , और थ्रेड बी डेटा का उपयोग करते हैं और फिर बफर को मुक्त करते हैं (क्योंकि थ्रेड बी में थ्रेड ए के ढेर तक पहुंच नहीं है, थ्रेड बी बफर को मुक्त नहीं कर सकता है, सबसे अच्छा थ्रेड बी क्या कर सकता है वापस थ्रेड ए पर थ्रेड पास कर सकता है; फिर से और थ्रेड ए इसे मुक्त करें)।
जेरेमी फ्रेज़र

9

डिफ़ॉल्ट रूप से, C में केवल एक ही ढेर है।

उस ने कहा, कुछ एलोकेटर जो थ्रेड अवगत हैं, ढेर का विभाजन करेंगे ताकि प्रत्येक थ्रेड के पास खुद को आवंटित करने का क्षेत्र हो। विचार यह है कि यह ढेर पैमाने को बेहतर बनाना चाहिए।

ऐसे ढेर का एक उदाहरण होर्ड है


डिफ़ॉल्ट रूप से, और C ++ में, कई थ्रेड नहीं हैं। 2003 c ++ विनिर्देश कम से कम अपने वर्चुअल मशीन डिज़ाइन में थ्रेड के लिए कोई भत्ता नहीं देता है, इसलिए c ++ में थ्रेड्स, कार्यान्वयन को परिभाषित करते हैं।
क्रिस बेके

यहां तक ​​कि अगर अलग-अलग थ्रेड्स को ढेर पर आवंटित करने के लिए अलग-अलग क्षेत्र हैं, तो भी वे किसी अन्य थ्रेड द्वारा आवंटित डेटा को देख सकते हैं, इसलिए थ्रेड्स अभी भी एक ही ढेर साझा करते हैं।
केन ब्लूम

1
अद्यतन: C ++ 11 थ्रेड्स के रूप में अब क्रियान्वयन को परिभाषित नहीं किया गया है।
माइकल डोरस्ट

5

ओएस पर निर्भर करता है। खिड़कियों और यूनियनों पर मानक सी रनटाइम धागे के पार एक साझा ढेर का उपयोग करता है। इसका मतलब है हर मॉलॉक / फ्री में लॉक करना।

सिम्बियन पर, उदाहरण के लिए, प्रत्येक थ्रेड अपने स्वयं के ढेर के साथ आता है, हालांकि थ्रेड्स किसी भी ढेर में आवंटित डेटा को संकेत साझा कर सकते हैं। सिम्बियन का डिज़ाइन मेरे विचार से बेहतर है क्योंकि यह न केवल आवंटन / मुफ्त के दौरान लॉकिंग की आवश्यकता को समाप्त करता है, बल्कि थ्रेड्स के बीच डेटा स्वामित्व के स्वच्छ विनिर्देश को भी प्रोत्साहित करता है। उस मामले में भी जब एक धागा मर जाता है, तो वह अपने साथ आवंटित सभी वस्तुओं को अपने साथ ले जाता है - अर्थात यह उन वस्तुओं को लीक नहीं कर सकता है जिन्हें यह आवंटित किया गया है, जो कि एक महत्वपूर्ण संपत्ति है जिसके पास विवश स्मृति वाले मोबाइल उपकरणों में है।

एर्लैंग भी इसी तरह के डिजाइन का अनुसरण करता है जहां "प्रक्रिया" कचरा संग्रहण की एक इकाई के रूप में कार्य करती है। सभी डेटा को कॉपी करके प्रक्रियाओं के बीच संप्रेषित किया जाता है, बाइनरी ब्लॉब्स को छोड़कर जो संदर्भ में गिने जाते हैं (मुझे लगता है)।


3

प्रत्येक थ्रेड का अपना स्टैक और कॉल स्टैक होता है।

प्रत्येक धागा एक ही ढेर साझा करता है।


3

यह इस बात पर निर्भर करता है कि "हीप" कहते समय आपका वास्तव में क्या मतलब है।

सभी थ्रेड्स पता स्थान साझा करते हैं, इसलिए ढेर-आवंटित ऑब्जेक्ट सभी थ्रेड्स से पहुंच योग्य हैं। तकनीकी रूप से, स्टैक को इस अर्थ में भी साझा किया जाता है, अर्थात कुछ भी आपको अन्य थ्रेड के स्टैक तक पहुँचने से रोकता है (हालाँकि ऐसा करने का लगभग कोई मतलब नहीं होगा)।

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


1

आमतौर पर, थ्रेड्स ढेर और अन्य संसाधनों को साझा करते हैं, हालांकि थ्रेड जैसे निर्माण होते हैं जो नहीं करते हैं। इन थ्रेड-जैसे निर्माणों में एरलैंग की हल्की प्रक्रियाएँ हैं, और UNIX की पूर्ण-प्रक्रियाएँ (कॉल के साथ बनाई गई fork()) हैं। आप मल्टी-मशीन कंसीडर पर भी काम कर रहे होंगे, इस स्थिति में आपके इंटर-थ्रेड कम्युनिकेशन विकल्प काफी सीमित हैं।


मैंने सोचा था कि कांटा एक नई प्रक्रिया बनाने की तरह है जो सिर्फ डेटा को एक नए मेमोरी लोकेशन में कॉपी करता है।
जेसन थोलस्ट्रुप

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

1

आम तौर पर बोलते हुए, सभी धागे एक ही पते की जगह का उपयोग करते हैं और इसलिए आमतौर पर सिर्फ एक ढेर होता है।

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

Windows- विशिष्ट: TLS- स्पेस को TlsAlloc का उपयोग करके आवंटित किया जा सकता है और TlsFree ( यहाँ अवलोकन ) का उपयोग करके मुक्त किया जा सकता है । फिर, यह एक ढेर नहीं है, बस DWORD है।

अजीब तरह से, विंडोज प्रति प्रक्रिया कई हीप का समर्थन करता है। एक हील्स के हैंडल को टीएलएस में स्टोर कर सकता है। तब आपके पास "थ्रेड-लोकल हीप" जैसा कुछ होगा। हालाँकि, केवल हैंडल अन्य थ्रेड्स के लिए ज्ञात नहीं है, वे अभी भी पॉइंटर्स का उपयोग करके इसकी मेमोरी तक पहुंच सकते हैं क्योंकि यह अभी भी एक ही एड्रेस स्पेस है।

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


> "अजीब तरह से, विंडोज प्रति प्रक्रिया में कई हीप्स का समर्थन करता है।", यह बिल्कुल अजीब नहीं है, एक व्यक्ति विभिन्न प्रकार के आवंटन के लिए विभिन्न ढेर का उपयोग कर सकता है, बस अधिक लचीलापन जोड़ता है। बेशक आप हमेशा VirtualAlloc के लिए नीचे उतर सकते हैं, और अपनी खुद की हीप का निर्माण कर सकते हैं।

1

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.