सामान्य रूप में क्या धागे साझा करते हैं?


20

वैसे यह सामान्य प्रश्न है। और अगर कोई इसे कार्यान्वयन के लिए विशिष्ट बनाना चाहता है तो मैं यूनिक्स से संबंधित सामान पसंद करूंगा। लेकिन पहले सामान्यता में निम्नलिखित समस्याओं को जानने की जरूरत है:

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

  1. ग्लोबल वैरिएबल - मैंने थ्रेड शेयर ग्लोबल वैरिएबल पढ़े हैं। जावा और सी # में प्रोग्रामिंग करते समय, मैंने कक्षा स्तर के चर साझा करने के लिए धागे बनाए हैं। इसलिए मुझे विश्वास है कि सूत्र वैश्विक चर साझा करते हैं (हालांकि यह सुनिश्चित नहीं है कि उच्च स्तरीय प्रोग्रामिंग भाषाओं में अवधारणाएं निम्न ऑपरेटिंग सिस्टम स्तर के तथ्यों के रूप में अनुवादित हैं)।

  2. ढेर - चूंकि वैश्विक चर को ढेर में संग्रहीत किया जाता है, इसलिए ढेर धागे के बीच साझा किया जाता है।

  3. स्टैक - चूंकि प्रत्येक थ्रेड का अपना निष्पादन अनुक्रम / कोड हो सकता है, इसका अपना स्टैक होना चाहिए, जिस पर यह अपने प्रोग्राम काउंटर कंटेंट को पुश / पॉप कर सकता है (जब कहते हैं कि फ़ंक्शन कॉल और रिटर्न होता है)। तो उसी प्रक्रिया के धागे स्टैक साझा नहीं करते हैं।

अब मैं निम्नलिखित चीजों के बंटवारे को लेकर अनिश्चित हूं

  1. पता स्थान - निश्चित नहीं कि पता स्थान के अंतर्गत वास्तव में क्या मायने रखता है। लेकिन मुझे लगता है कि पता स्थान आमतौर पर प्रक्रियाओं के संदर्भ में उपयोग किया जाता है, न कि थ्रेड्स। और चूंकि एक ही प्रक्रिया के सभी थ्रेड्स अभिभावक प्रक्रिया के समान एड्रेस स्पेस में रहते हैं, इसलिए कहा जाता है कि थ्रेड्स एड्रेस स्पेस को साझा करते हैं। (लेकिन फिर वे एक ही एड्रेस स्पेस के अंदर अलग-अलग स्टैक बनाए रखते हैं?)

  2. ओएस संसाधन - मुझे लगता है कि यह बहुत कार्यान्वयन विशिष्ट हो सकता है। उदाहरण के लिए, माता-पिता की प्रक्रिया अपने कुछ थ्रेड्स के लिए उसी फ़ाइल का चयन चुन सकती है और सभी को नहीं। या मैं गलत कर रहा हूं और ओएस संसाधनों का मतलब फाइलों के अलावा कुछ है?

  3. कोड - थ्रेड्स में भिन्न कोड हो सकते हैं, इसलिए कोड साझा करना हमेशा ऐसा नहीं होता है।

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

कुल मिलाकर मैं अस्पष्ट शब्दों के कारण काफी उलझन में हूं, ऑपरेटिंग सिस्टम की पुस्तकों में किए गए सुपर-सामान्यीकरण और ऑनलाइन प्रदान किए गए अतिरिक्त-कार्यान्वयन विशिष्ट विवरण। इसलिए मैं कुछ उत्तर खोजने की कोशिश कर रहा हूं जो मुझे संतुष्ट कर सकें।

जवाबों:


13

सामान्य तौर पर प्रत्येक धागे के अपने रजिस्टर (अपने प्रोग्राम काउंटर सहित), अपने स्वयं के स्टैक पॉइंटर और अपने स्वयं के स्टैक होते हैं। एक प्रक्रिया को साझा करने वाले थ्रेड्स के बीच बाकी सब कुछ साझा किया जाता है।

विशेष रूप से एक प्रक्रिया को आम तौर पर पता स्थान, ढेर, स्थिर डेटा और कोड सेगमेंट और फ़ाइल डिस्क्रिप्टर * साझा करने वाले थ्रेड्स के एक सेट से मिलकर माना जाता है ।

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

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

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


4

ऑपरेटिंग सिस्टम और प्रोग्रामिंग भाषाओं: थ्रेड्स दो दृष्टिकोणों में सामने आते हैं। दोनों ही स्थिति में, थ्रेड की विशेषता में कुछ भिन्नता है।

एक धागे की न्यूनतम परिभाषा यह है कि यह सामान है जो क्रम में होता है, एक के बाद एक चीजें।

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

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

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

गणना के समय के अलावा अधिकांश ऑपरेटिंग सिस्टम संसाधन कार्यों से जुड़े होते हैं, न कि थ्रेड्स। कुछ ऑपरेटिंग सिस्टम (उदाहरण के लिए, लिनक्स) स्पष्ट रूप से स्टैमिट स्टैक करते हैं, जिस स्थिति में प्रत्येक थ्रेड का अपना होता है; लेकिन वहाँ OSes हैं जहाँ कर्नेल को ढेर के बारे में कुछ भी पता नहीं है, वे अभी तक ढेर का हिस्सा हैं जहाँ तक यह चिंतित है। कर्नेल भी आमतौर पर प्रत्येक थ्रेड के लिए कर्नेल संदर्भ का प्रबंधन करता है, जो एक डेटा संरचना है जिसमें थ्रेड वर्तमान में क्या कर रहा है के बारे में जानकारी है; यह कर्नेल को एक ही समय में एक सिस्टम कॉल में अवरुद्ध कई धागों को संभालने की सुविधा देता है।

जहाँ तक ऑपरेटिंग सिस्टम का सवाल है, किसी कार्य के थ्रेड्स एक ही कोड को चलाते हैं, लेकिन उस कोड में अलग-अलग स्थिति में हैं (अलग-अलग प्रोग्राम काउंटर वैल्यू)। ऐसा हो सकता है या नहीं भी हो सकता है कि किसी प्रोग्राम के कोड के कुछ हिस्से हमेशा एक विशिष्ट थ्रेड में निष्पादित होते हैं, लेकिन आमतौर पर कॉमन कोड (जैसे यूटिलिटी फ़ंक्शंस) होते हैं जिन्हें किसी भी थ्रेड से कहा जा सकता है। सभी थ्रेड्स समान डेटा देखते हैं, अन्यथा उन्हें विभिन्न कार्यों पर विचार किया जाएगा; यदि कुछ डेटा को केवल एक विशेष थ्रेड द्वारा एक्सेस किया जा सकता है, तो यह आमतौर पर केवल प्रोग्रामिंग भाषा के दायरे में होता है, ऑपरेटिंग सिस्टम का नहीं।

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

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

कुछ भाषाओं ने थ्रेड-लोकल स्टोरेज को वैश्विक स्तर से अलग करने के लिए थ्रेड-लोकल स्टोरेज के साथ या बिना टाइप सिस्टम के दोनों मॉडलों को मिलाया है। थ्रेड-लोकल स्टोरेज आमतौर पर एक सुविधा सुविधा है जो एक वैरिएबल नाम को अलग-अलग थ्रेड में अलग-अलग स्टोरेज लोकेशनों को नामित करने की अनुमति देती है।

कुछ (कठिन) फॉलो-अप जो कि यह समझने में रुचि रखते हैं कि धागे क्या हैं:

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

यह सबसे दिलचस्प बात है जो मैंने महीनों में पढ़ी है।
JSON

2

वह निर्भर करता है। यदि आप थ्रेड्स को POSIX द्वारा परिभाषित के रूप में मानते हैं (और यूनिक्स सिस्टम द्वारा पेश किया गया है) या विंडोज द्वारा (बाद में परिचित नहीं है, तो आपको विशेष रूप से पूछना होगा), तो वह आपका जवाब देता है (अनिवार्य रूप से @WanderingLogic उत्तर बताता है)। गैर-मानक clone(2)प्रणाली कॉल का उपयोग करके लिनक्स के पास थ्रेड्स का अपना विचार है । यह माता-पिता और बच्चे के हिस्से के बजाए ठीक-ठाक नियंत्रण प्रदान करता है। यह आंतरिक के चारों ओर जहाँ तक fork(2)और vfork(2)अनिवार्य रूप से रैपर होता है clone(2), इसे विशिष्ट झंडे के साथ कहते हैं, अर्थात, आप "थ्रेड्स" बना सकते हैं जो माता-पिता के साथ कुछ भी नहीं है। विवरण के लिए इसके मैनुअल पेज को देखें, वे यहां ऑनलाइन उपलब्ध हैं । हाँ, लिनक्स POSIX शैली के धागे प्रदान करता है, लेकिन इसके अलावा भी बहुत कुछ।


0

धागे साझा करें:

  • पता स्थान
  • ढेर
  • स्थैतिक डेटा
  • कोड खंड
  • फ़ाइल विवरणक
  • सार्वत्रिक चर
  • बाल प्रक्रिया
  • लंबित अलार्म
  • सिग्नल और सिग्नल हैंडलर
  • लेखांकन जानकारी

धागे का अपना है:

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