मुझे लगा कि मल्टी-कोर कंप्यूटर की बात यह है कि यह एक साथ कई थ्रेड चला सकता है। उस स्थिति में, यदि आपके पास क्वाड-कोर मशीन है, तो एक बार में 4 से अधिक धागे होने की क्या बात है? क्या वे सिर्फ एक-दूसरे से समय (CPU संसाधन) नहीं चुरा रहे होंगे?
मुझे लगा कि मल्टी-कोर कंप्यूटर की बात यह है कि यह एक साथ कई थ्रेड चला सकता है। उस स्थिति में, यदि आपके पास क्वाड-कोर मशीन है, तो एक बार में 4 से अधिक धागे होने की क्या बात है? क्या वे सिर्फ एक-दूसरे से समय (CPU संसाधन) नहीं चुरा रहे होंगे?
जवाबों:
उत्तर धागे के उद्देश्य के आसपास घूमता है, जो समानता है: एक ही बार में निष्पादन की कई अलग-अलग लाइनें चलाने के लिए। एक 'आदर्श' प्रणाली में, आपके पास प्रति कोर एक धागा निष्पादन होगा: कोई रुकावट नहीं। वास्तव में यह मामला नहीं है। यहां तक कि अगर आपके पास चार कोर और चार काम करने वाले धागे हैं, तो आपकी प्रक्रिया और यह धागे लगातार अन्य प्रक्रियाओं और थ्रेड्स के लिए स्विच किए जाएंगे। यदि आप कोई आधुनिक ओएस चला रहे हैं, तो हर प्रक्रिया में कम से कम एक धागा है, और कई में अधिक है। ये सभी प्रक्रियाएं एक ही बार में चल रही हैं। आपके पास अभी कई सौ धागे हैं जो अभी आपकी मशीन पर चल रहे हैं। आपको कभी भी ऐसी स्थिति नहीं मिलेगी जहां कोई थ्रेड बिना समय के 'चोरी' से चलता हो। (ठीक है, आप अगर यह वास्तविक समय चल रहा है हो सकता है, अगर आप एक realtime OS का उपयोग कर रहे हैं या, यहां तक कि विंडोज पर भी, एक रीयल-टाइम थ्रेड प्राथमिकता का उपयोग करें। लेकिन यह दुर्लभ है।)
उस पृष्ठभूमि के साथ, उत्तर: हां, एक सच्चे चार-कोर मशीन पर चार से अधिक धागे आपको एक ऐसी स्थिति दे सकते हैं, जहां वे 'एक दूसरे से समय चुराते हैं', लेकिन केवल अगर प्रत्येक व्यक्ति को 100% सीपीयू की आवश्यकता होती है । यदि कोई थ्रेड 100% काम नहीं कर रहा है (जैसा कि यूआई थ्रेड नहीं हो सकता है, या एक थ्रेड थोड़ी मात्रा में काम कर रहा है या किसी और चीज़ पर प्रतीक्षा कर रहा है) तो एक और थ्रेड अनुसूचित होना वास्तव में एक अच्छी स्थिति है।
यह वास्तव में उससे अधिक जटिल है:
क्या होगा अगर आपके पास काम के पांच बिट्स हैं जो सभी को एक बार में करने की आवश्यकता है? यह उन सभी को एक साथ चलाने के लिए अधिक समझ में आता है, उनमें से चार को चलाने के लिए और फिर बाद में पांचवें को चलाने के लिए।
यह वास्तव में 100% सीपीयू के लिए एक धागे के लिए दुर्लभ है। जिस क्षण यह डिस्क या नेटवर्क I / O का उपयोग करता है, उदाहरण के लिए, यह संभावित रूप से समय व्यतीत कर सकता है जो कुछ भी उपयोगी नहीं है। यह एक बहुत ही सामान्य स्थिति है।
यदि आपके पास काम है जिसे चलाने की आवश्यकता है, तो एक सामान्य तंत्र एक थ्रेडपूल का उपयोग करना है। यह कोर के रूप में धागे की एक ही संख्या के लिए समझ बनाने के लिए लग सकता है, फिर भी .net थ्रेडपूल में 250 प्रोसेसर तक उपलब्ध धागे हैं । मुझे यकीन नहीं है कि वे ऐसा क्यों करते हैं, लेकिन मेरा अनुमान उन कार्यों के आकार के साथ करना है जो थ्रेड्स पर चलने के लिए दिए गए हैं।
तो: समय चुराना कोई बुरी बात नहीं है (और यह वास्तव में चोरी नहीं है, या तो: यह है कि सिस्टम को कैसे काम करना चाहिए।) अपने मल्टीथ्रेडेड प्रोग्रामों को लिखें कि थ्रेड्स किस तरह का काम करेंगे, जो सीपीयू नहीं हो सकता है। -bound। रूपरेखा और माप के आधार पर आपके द्वारा आवश्यक थ्रेड्स की संख्या का पता लगाएं। आपको थ्रेड्स के बजाय कार्यों या नौकरियों के संदर्भ में सोचना अधिक उपयोगी हो सकता है: काम की वस्तुओं को लिखें और उन्हें चलाने के लिए एक पूल दें। अंत में, जब तक कि आपका कार्यक्रम वास्तव में प्रदर्शन-महत्वपूर्ण न हो, तब तक बहुत चिंता न करें :)
सिर्फ इसलिए कि एक धागा मौजूद है इसका मतलब यह नहीं है कि यह सक्रिय रूप से चल रहा है। थ्रेड्स के कई अनुप्रयोगों में सोते हुए कुछ धागे शामिल होते हैं, जब तक कि उनके लिए कुछ करने का समय न हो - उदाहरण के लिए, उपयोगकर्ता इनपुट जागने के लिए थ्रेड ट्रिगर करते हैं, कुछ प्रसंस्करण करते हैं, और सोने के लिए वापस जाते हैं।
अनिवार्य रूप से, थ्रेड्स व्यक्तिगत कार्य हैं जो एक दूसरे के स्वतंत्र रूप से काम कर सकते हैं, किसी अन्य कार्य की प्रगति के बारे में जागरूक होने की आवश्यकता नहीं है। यह संभव है कि इनमें से अधिक से अधिक आप एक साथ चलाने की क्षमता रखते हैं; वे अभी भी सुविधा के लिए उपयोगी हैं भले ही उन्हें कभी-कभी एक-दूसरे के पीछे लाइन में इंतजार करना पड़े।
मुद्दा यह है कि, जब थ्रेड काउंट कोर काउंट से अधिक होता है, तो कोई वास्तविक स्पीडअप नहीं मिलने के बावजूद, आप थ्रेड का उपयोग तर्क के टुकड़े को अलग करने के लिए कर सकते हैं, जिसका अन्योन्याश्रित होना आवश्यक नहीं है।
यहां तक कि एक मामूली जटिल अनुप्रयोग में, एक ही धागे का उपयोग करके सब कुछ जल्दी से करने की कोशिश करना आपके कोड के 'प्रवाह' का हैश बनाता है। एकल धागा अपना अधिकांश समय इस पर खर्च करने, उस पर जाँच करने, आवश्यकतानुसार सशर्त रूप से रूटीन कॉल करने में बिताता है, और यह कुछ भी देखना मुश्किल हो जाता है, लेकिन माइनुटिया की नैतिकता।
इसके विपरीत इस मामले में जहां आप थ्रेड्स को कार्यों के लिए समर्पित कर सकते हैं ताकि, किसी भी व्यक्तिगत थ्रेड को देखते हुए, आप देख सकें कि वह थ्रेड क्या कर रहा है। उदाहरण के लिए, एक थ्रेड किसी सॉकेट से इनपुट पर प्रतीक्षा को अवरुद्ध कर सकता है, धारा को संदेशों में फ़िल्टर कर सकता है, संदेशों को फ़िल्टर कर सकता है, और जब एक वैध संदेश आता है, तो इसे किसी अन्य कार्यकर्ता थ्रेड में भेज दें। वर्कर थ्रेड कई अन्य स्रोतों से इनपुट पर काम कर सकता है। इनमें से प्रत्येक के लिए कोड एक साफ, उद्देश्यपूर्ण प्रवाह का प्रदर्शन करेगा, बिना स्पष्ट जांच किए कि ऐसा कुछ और नहीं है।
इस तरह से काम को विभाजित करने से आपके आवेदन को सीपीयू के साथ आगे क्या करना है, यह निर्धारित करने के लिए ऑपरेटिंग सिस्टम पर भरोसा करने की अनुमति मिलती है, इसलिए आपको अपने आवेदन में हर जगह स्पष्ट सशर्त जांच करने की आवश्यकता नहीं है कि क्या हो सकता है और क्या प्रक्रिया के लिए तैयार है।
यदि कोई थ्रेड किसी संसाधन की प्रतीक्षा कर रहा है (जैसे RAM से मान को किसी रजिस्टर में लोड करना, डिस्क I / O, नेटवर्क एक्सेस, एक नई प्रक्रिया लॉन्च करना, एक डेटाबेस क्वेरी करना या उपयोगकर्ता इनपुट की प्रतीक्षा करना), प्रोसेसर एक सर्वर पर काम कर सकता है संसाधन उपलब्ध होने के बाद अलग धागा, और पहले धागे पर वापस लौटें। यह उस समय को कम कर देता है, जब CPU बेकार में खर्च होता है, क्योंकि सीपीयू बेकार बैठे रहने के बजाय लाखों ऑपरेशन कर सकता है।
एक थ्रेड पर विचार करें जिसे हार्ड ड्राइव से डेटा पढ़ने की आवश्यकता है। 2014 में, एक सामान्य प्रोसेसर कोर 2.5 GHz पर काम करता है और प्रति चक्र 4 निर्देशों को निष्पादित करने में सक्षम हो सकता है। 0.4 ns के चक्र समय के साथ, प्रोसेसर 10 निर्देश प्रति नैनोसेकंड निष्पादित कर सकता है। विशिष्ट यांत्रिक हार्ड ड्राइव की तलाश के साथ समय लगभग 10 मिलीसेकंड होता है, प्रोसेसर उस समय में 100 मिलियन निर्देशों को निष्पादित करने में सक्षम होता है जब हार्ड ड्राइव से एक मूल्य पढ़ने में लगता है। हार्ड कैश के साथ हार्ड ड्राइव (4 एमबी बफर) और कुछ जीबी स्टोरेज के साथ हाइब्रिड ड्राइव के साथ महत्वपूर्ण प्रदर्शन में सुधार हो सकता है, क्योंकि हाइब्रिड खंड से अनुक्रमिक रीड या रीड के लिए डेटा विलंबता तेज परिमाण के कई आदेश हो सकते हैं।
एक प्रोसेसर कोर थ्रेड्स के बीच स्विच कर सकता है (एक थ्रेड को फिर से शुरू करने और फिर से शुरू करने के लिए लागत लगभग 100 घड़ी चक्र है) जबकि पहला धागा एक उच्च विलंबता इनपुट (रजिस्टरों (1 घड़ी) और रैम (5 नैनोमीटर बादलों की तुलना में अधिक महंगा कुछ भी) के लिए इंतजार करता है) में शामिल हैं डिस्क I / O, नेटवर्क एक्सेस (250ms की विलंबता), सीडी या धीमी बस या डेटाबेस कॉल से डेटा पढ़ना। कोर की तुलना में अधिक थ्रेड होने का मतलब है कि उपयोगी काम किया जा सकता है जबकि उच्च-विलंबता कार्यों को हल किया जाता है।
CPU में एक थ्रेड शेड्यूलर है जो प्रत्येक थ्रेड को प्राथमिकता देता है, और एक थ्रेड को सोने की अनुमति देता है, फिर एक पूर्व निर्धारित समय के बाद फिर से शुरू करें। यह थ्रेडिंग को कम करने के लिए थ्रेड शेड्यूलर का काम है, जो तब होगा जब प्रत्येक थ्रेड को फिर से सोने से पहले सिर्फ 100 निर्देशों को निष्पादित किया जाए। स्विचिंग थ्रेड्स का ओवरहेड प्रोसेसर कोर के कुल उपयोगी थ्रूपुट को कम करेगा।
इस कारण से, आप अपनी समस्या को उचित संख्या में थ्रेड तक तोड़ना चाह सकते हैं। यदि आप मैट्रिक्स गुणन करने के लिए कोड लिख रहे थे, तो आउटपुट मैट्रिक्स में एक थ्रेड प्रति सेल बनाना अत्यधिक हो सकता है, जबकि आउटपुट मैट्रिक्स में प्रति पंक्ति या एन पंक्तियों में एक थ्रेड बनाने, थ्रेडिंग और रिज्यूमिंग थ्रेड्स के ओवरहेड लागत को कम कर सकता है।
यही कारण है कि शाखा की भविष्यवाणी महत्वपूर्ण है। यदि आपके पास एक स्टेटमेंट है, जिसमें RAM से मान लोड करने की आवश्यकता है, लेकिन if और अन्य विवरणों का मुख्य भाग पहले से ही रजिस्टरों में लोड किए गए मानों का उपयोग करता है, तो प्रोसेसर स्थिति का मूल्यांकन करने से पहले एक या दोनों शाखाओं को निष्पादित कर सकता है। एक बार स्थिति वापस आने पर, प्रोसेसर संबंधित शाखा के परिणाम को लागू करेगा और दूसरे को छोड़ देगा। यहां संभावित रूप से बेकार काम करना संभवतः एक अलग धागे पर स्विच करने से बेहतर है, जिससे थ्रैशिंग हो सकती है।
जैसा कि हम उच्च क्लॉक-स्पीड सिंगल-कोर प्रोसेसर से मल्टी-कोर प्रोसेसर से दूर चले गए हैं, चिप डिजाइन ने प्रति व्यक्ति अधिक कोर को समेटने पर ध्यान केंद्रित किया है, कोर के बीच ऑन-चिप संसाधन साझाकरण में सुधार, बेहतर शाखा पूर्वानुमान एल्गोरिदम, बेहतर थ्रेड स्विचिंग ओवरहेड, और बेहतर धागा निर्धारण।
ऊपर दिए गए अधिकांश उत्तर प्रदर्शन और एक साथ संचालन के बारे में बात करते हैं। मैं इसे एक अलग कोण से देखने जा रहा हूँ।
चलो, एक सरलीकृत टर्मिनल अनुकरण कार्यक्रम के मामले को कहते हैं। आपको निम्नलिखित काम करने होंगे:
(रियल टर्मिनल एमुलेटर अधिक प्रदर्शन सहित आपके द्वारा टाइप किए गए सामान को संभावित रूप से प्रतिध्वनित करते हुए अधिक करते हैं, लेकिन हम अभी के लिए उस पर से गुजरेंगे।)
अब दूरस्थ से पढ़ने के लिए लूप सरल है, निम्न सूडोकोड के अनुसार:
while get-character-from-remote:
print-to-screen character
कीबोर्ड की निगरानी और भेजने के लिए लूप भी सरल है:
while get-character-from-keyboard:
send-to-remote character
हालाँकि, समस्या यह है कि आपको यह एक साथ करना होगा। यदि आपके पास थ्रेडिंग नहीं है, तो कोड को अब इस तरह देखना होगा:
loop:
check-for-remote-character
if remote-character-is-ready:
print-to-screen character
check-for-keyboard-entry
if keyboard-is-ready:
send-to-remote character
तर्क, यहां तक कि इस जानबूझकर सरलीकृत उदाहरण में, जो संचार की वास्तविक-विश्व जटिलता को ध्यान में नहीं रखता है, काफी अस्पष्ट है। थ्रेडिंग के साथ, हालांकि, यहां तक कि एक कोर पर, दो स्यूडोकोड लूप स्वतंत्र रूप से अपने तर्क को इंटरलेस किए बिना मौजूद हो सकते हैं। चूंकि दोनों धागे ज्यादातर I / O- बाउंड होंगे, इसलिए वे सीपीयू पर भारी भार नहीं डालते हैं, भले ही वे कड़ाई से बोल रहे हों, एकीकृत लूप की तुलना में सीपीयू संसाधनों की अधिक बर्बादी होगी।
अब निश्चित रूप से वास्तविक दुनिया का उपयोग ऊपर से अधिक जटिल है। लेकिन एकीकृत लूप की जटिलता तेजी से बढ़ जाती है क्योंकि आप अनुप्रयोग में अधिक चिंताएँ जोड़ते हैं। तर्क कभी भी अधिक विखंडित हो जाता है और आपको प्रबंधनीय चीजों को प्राप्त करने के लिए राज्य मशीनों, कोरटाइन, एट अल जैसी तकनीकों का उपयोग करना शुरू करना पड़ता है। प्रबंधनीय, लेकिन पठनीय नहीं। थ्रेडिंग कोड को अधिक पठनीय रखता है।
तो आप थ्रेडिंग का उपयोग क्यों नहीं करेंगे?
ठीक है, अगर आपके कार्य I / O- बाउंड के बजाय CPU-बाध्य हैं, तो थ्रेडिंग वास्तव में आपके सिस्टम को धीमा कर देती है। प्रदर्शन से नुकसान होगा। बहुत, कई मामलों में। ("थ्रैशिंग" एक सामान्य समस्या है यदि आप बहुत अधिक सीपीयू-बाउंड थ्रेड्स को छोड़ देते हैं। आप थ्रेड्स की सामग्री को स्वयं चलाने की तुलना में सक्रिय थ्रेड्स को बदलने में अधिक समय व्यतीत करते हैं।) इसके अलावा, ऊपर दिए गए तर्क के कारणों में से एक है। इतना सरल है कि मैंने बहुत जानबूझकर एक सरलीकृत (और अवास्तविक) उदाहरण चुना है। यदि आप स्क्रीन पर टाइप किया गया गूंज चाहते थे तो आपको साझा संसाधनों की लॉकिंग शुरू करने के साथ चोट की एक नई दुनिया मिल गई है। केवल एक साझा संसाधन के साथ यह इतनी समस्या नहीं है, लेकिन यह एक बड़ी और बड़ी समस्या बनने लगती है क्योंकि आपके पास साझा करने के लिए अधिक संसाधन हैं।
तो अंत में, थ्रेडिंग कई चीजों के बारे में है। उदाहरण के लिए, यह आई / ओ-बाउंड प्रक्रियाओं को और अधिक उत्तरदायी बनाने (भले ही कम कुशल समग्र) बनाने के बारे में हो जैसा कि कुछ पहले ही कह चुके हैं। यह तर्क को आसान बनाने के बारे में है (लेकिन केवल यदि आप साझा स्थिति को कम करते हैं)। यह बहुत सारे सामान के बारे में है, और आपको यह तय करना होगा कि क्या इसके फायदे मामले के आधार पर इसके नुकसान को कम कर देते हैं।
यद्यपि आप निश्चित रूप से अपने हार्डवेयर के आधार पर गणना में तेजी लाने के लिए थ्रेड्स का उपयोग कर सकते हैं, उनका मुख्य उपयोग उपयोगकर्ता-मित्रता कारणों से एक समय में एक से अधिक काम करना है।
उदाहरण के लिए, यदि आपको पृष्ठभूमि में कुछ प्रसंस्करण करना है और यूआई इनपुट के लिए भी उत्तरदायी है, तो आप थ्रेड का उपयोग कर सकते हैं। थ्रेड्स के बिना, उपयोगकर्ता इंटरफ़ेस हर बार आपके द्वारा किसी भी भारी प्रसंस्करण को करने की कोशिश करने पर लटका होगा।
इस संबंधित प्रश्न को भी देखें: थ्रेड्स के लिए व्यावहारिक उपयोग
मैं @ kyoryu के जोर से असहमत हूं कि आदर्श संख्या प्रति CPU एक धागा है।
इसके बारे में इस तरह से सोचें: हमारे पास मल्टी-प्रोसेसिंग ऑपरेटिंग सिस्टम क्यों है? अधिकांश कंप्यूटर इतिहास के लिए, लगभग सभी कंप्यूटरों में एक CPU था। फिर भी 1960 के दशक से, सभी "वास्तविक" कंप्यूटरों में मल्टी-प्रोसेसिंग (उर्फ मल्टी-टास्किंग) ऑपरेटिंग सिस्टम था।
आप कई प्रोग्राम चलाते हैं ताकि कोई चला सके जबकि अन्य आईओ जैसी चीजों के लिए अवरुद्ध हो।
एनटी से पहले विंडोज संस्करण मल्टी टास्किंग थे या नहीं, इसके बारे में अलग तर्क प्रस्तुत करते हैं। तब से, हर वास्तविक ओएस में मल्टी-टास्किंग थी। कुछ इसे उपयोगकर्ताओं के लिए उजागर नहीं करते हैं, लेकिन इसके वैसे भी, सेलफोन रेडियो को सुनने, जीपीएस चिप से बात करना, माउस इनपुट को स्वीकार करना आदि जैसे कार्य करते हैं।
थ्रेड्स ऐसे कार्य हैं जो थोड़े अधिक कुशल हैं। किसी कार्य, प्रक्रिया और धागे के बीच कोई बुनियादी अंतर नहीं है।
एक सीपीयू बर्बाद करने के लिए एक भयानक चीज है, इसलिए जब आप यह कर सकते हैं तो बहुत सारी चीजें इसका उपयोग करने के लिए तैयार हैं।
मैं इस बात से सहमत हूँ कि अधिकांश प्रक्रियात्मक भाषाओं, C, C ++, Java आदि के साथ, उचित थ्रेड सेफ कोड लिखना बहुत काम का है। आज बाजार पर 6 कोर सीपीयू के साथ, और 16 कोर सीपीयू दूर नहीं हैं, मुझे उम्मीद है कि लोग इन पुरानी भाषाओं से दूर हो जाएंगे, क्योंकि मल्टी-थ्रेडिंग एक महत्वपूर्ण आवश्यकता से अधिक है।
@Kyoryu से असहमति सिर्फ IMHO है, बाकी तथ्य यह है।
एक वेब सर्वर की कल्पना करें, जिसे कई मनमाने अनुरोधों को पूरा करना है। आपको अनुरोधों को समानांतर रूप से सेवा करनी होगी क्योंकि अन्यथा प्रत्येक नए अनुरोध को तब तक इंतजार करना होगा जब तक कि अन्य सभी अनुरोधों को पूरा नहीं किया जाता है (इंटरनेट पर प्रतिक्रिया भेजने सहित)। इस मामले में, अधिकांश वेब सर्वरों के पास अनुरोधों की संख्या की तुलना में कम कोर होते हैं जो वे आमतौर पर सेवा करते हैं।
यह सर्वर के डेवलपर के लिए भी आसान बनाता है: आपको केवल एक थ्रेड प्रोग्राम लिखना होगा जो एक अनुरोध पर काम करता है, आपको कई अनुरोधों को संग्रहीत करने के बारे में सोचने की ज़रूरत नहीं है, जिस क्रम में आप उनकी सेवा करते हैं, और इसी तरह।
कई धागे सो रहे होंगे, उपयोगकर्ता इनपुट, I / O, और अन्य घटनाओं की प्रतीक्षा कर रहे हैं।
थ्रेड यूआई अनुप्रयोगों में जवाबदेही के साथ मदद कर सकते हैं। इसके अतिरिक्त, आप अपने कोर से अधिक काम पाने के लिए थ्रेड्स का उपयोग कर सकते हैं। उदाहरण के लिए, एक कोर पर, आप एक थ्रेड IO कर सकते हैं और दूसरा कुछ गणना कर सकते हैं। यदि यह सिंगल थ्रेडेड था, तो कोर अनिवार्य रूप से आइओ के पूरा होने के इंतजार में बेकार हो सकता है। यह एक उच्च स्तरीय उदाहरण है, लेकिन थ्रेड्स का उपयोग निश्चित रूप से आपके सीपीयू को थोड़ा कठिन बनाने के लिए किया जा सकता है।
प्रोसेसर, या सीपीयू, भौतिक चिप है जिसे सिस्टम में प्लग किया जाता है। एक प्रोसेसर में कई कोर हो सकते हैं (एक कोर चिप का हिस्सा है जो निर्देशों को निष्पादित करने में सक्षम है)। ऑपरेटिंग सिस्टम को कई वर्चुअल प्रोसेसर के रूप में दिखाया जा सकता है यदि यह एक साथ कई थ्रेड्स निष्पादित करने में सक्षम है (एक थ्रेड निर्देशों का एकल अनुक्रम है)।
एक प्रक्रिया एक आवेदन के लिए दूसरा नाम है। आम तौर पर, प्रक्रियाएं एक-दूसरे से स्वतंत्र होती हैं। यदि एक प्रक्रिया मर जाती है, तो यह दूसरी प्रक्रिया भी नहीं मरती है। प्रक्रियाओं के लिए यह संभव है कि वे स्मृति या I / O जैसे संसाधनों को साझा करें या साझा करें।
प्रत्येक प्रक्रिया का एक अलग पता स्थान और स्टैक होता है। एक प्रक्रिया में कई थ्रेड्स हो सकते हैं, प्रत्येक एक साथ निर्देशों को निष्पादित करने में सक्षम होते हैं। एक प्रक्रिया में सभी थ्रेड्स समान पता स्थान साझा करते हैं, लेकिन प्रत्येक थ्रेड का अपना स्टैक होगा।
उम्मीद है कि इन मूल सिद्धांतों का उपयोग करके इन परिभाषाओं और आगे के शोध से आपकी समझ में मदद मिलेगी।
धागे का आदर्श उपयोग, वास्तव में, प्रति कोर एक है।
हालाँकि, जब तक आप विशेष रूप से अतुल्यकालिक / गैर-अवरुद्ध IO का उपयोग नहीं करते हैं, तब तक एक अच्छा मौका है कि आपके पास कुछ बिंदु पर IO पर अवरुद्ध धागे होंगे, जो आपके CPU का उपयोग नहीं करेगा।
इसके अलावा, विशिष्ट प्रोग्रामिंग भाषाएं 1 थ्रेड प्रति सीपीयू का उपयोग करना थोड़ा मुश्किल बनाती हैं। संगामिति (जैसे एर्लांग) के आसपास डिज़ाइन की गई भाषाएँ अतिरिक्त थ्रेड्स का उपयोग नहीं करना आसान बना सकती हैं।
जिस तरह से कुछ एपीआई डिज़ाइन किए गए हैं, आपके पास उन्हें एक अलग थ्रेड (ब्लॉकिंग ऑपरेशन के साथ कुछ भी) में चलाने के अलावा कोई विकल्प नहीं है । एक उदाहरण पायथन का HTTP पुस्तकालय (AFAIK) होगा।
आमतौर पर यह एक समस्या नहीं है, हालांकि (यदि यह एक समस्या है, तो ओएस या एपीआई को वैकल्पिक एसिंक्रोनस ऑपरेटिंग मोड के साथ जहाज करना चाहिए, अर्थात:) select(2)
, क्योंकि इसका मतलब है कि धागा I / के इंतजार में सो रहा होगा / ओ पूरा करना। दूसरी ओर, अगर कुछ एक भारी गणना कर रहा है, आप के लिए है एक अलग थ्रेड में कहते हैं की तुलना में यह डाल करने के लिए, जीयूआई धागा (जब तक आप मैन्युअल बहुसंकेतन का आनंद)।
मुझे पता है कि यह एक सुपर पुराना सवाल है जिसमें बहुत सारे अच्छे उत्तर हैं, लेकिन मैं यहां कुछ ऐसा बता रहा हूं जो वर्तमान परिवेश में महत्वपूर्ण है:
यदि आप मल्टी-थ्रेडिंग के लिए एक एप्लिकेशन डिज़ाइन करना चाहते हैं, तो आपको किसी विशिष्ट हार्डवेयर सेटिंग के लिए डिज़ाइन नहीं करना चाहिए। सीपीयू प्रौद्योगिकी वर्षों से काफी तेजी से आगे बढ़ रही है, और कोर की गिनती लगातार बढ़ रही है। यदि आप जानबूझकर अपने एप्लिकेशन को ऐसे डिज़ाइन करते हैं कि वह केवल 4 थ्रेड का उपयोग करता है, तो आप संभावित रूप से अपने आप को ऑक्टा-कोर सिस्टम (उदाहरण के लिए) में प्रतिबंधित कर रहे हैं। अब, यहां तक कि 20-कोर सिस्टम व्यावसायिक रूप से उपलब्ध हैं, इसलिए ऐसा डिज़ाइन निश्चित रूप से अच्छे से अधिक नुकसान कर रहा है।
आपके पहले अनुमान के जवाब में: मल्टी-कोर मशीनें एक साथ कई प्रक्रियाएँ चला सकती हैं, न कि किसी एकल प्रक्रिया के कई सूत्र।
आपके पहले सवाल के जवाब में: कई थ्रेड्स का बिंदु आमतौर पर एक साथ कई कार्यों को एक अनुप्रयोग में करने के लिए होता है। नेट पर क्लासिक उदाहरण ईमेल भेजने और प्राप्त करने का एक ईमेल प्रोग्राम है, और एक वेब सर्वर पेज अनुरोधों को प्राप्त और भेज रहा है। (ध्यान दें कि विंडोज जैसी प्रणाली को केवल एक धागा या केवल एक प्रक्रिया चलाने के लिए कम करना असंभव है। विंडोज टास्क मैनेजर को चलाएं और आप आमतौर पर सक्रिय प्रक्रियाओं की एक लंबी सूची देखेंगे, जिनमें से कई कई थ्रेड चल रहे होंगे। )
आपके दूसरे प्रश्न के उत्तर में: अधिकांश प्रक्रियाएँ / धागे सीपीयू-बाउंड नहीं हैं (अर्थात, निरंतर और निर्बाध नहीं चल रहे हैं), लेकिन इसके बजाय रुकें और I / O के समाप्त होने के लिए अक्सर प्रतीक्षा करें। उस प्रतीक्षा के दौरान, अन्य प्रक्रियाएं / धागे वेटिंग कोड से "चोरी" के बिना भी चल सकते हैं (एक ही कोर मशीन पर भी)।
एक धागा एक अमूर्तता है जो आपको ऑपरेशन के अनुक्रम के रूप में सरल रूप से कोड लिखने में सक्षम बनाता है, इस बात से अनजान है कि कोड को अन्य कोड के साथ इंटरलेक्ट किया गया है, या आईओ के इंतजार में खड़ी है, या (शायद कुछ अधिक जागरूक) अन्य थ्रेड के इंतजार में घटनाओं या संदेश।
मुद्दा यह है कि अधिकांश प्रोग्रामर समझ नहीं पाते हैं कि राज्य मशीन को कैसे डिज़ाइन किया जाए। अपने स्वयं के धागे में सब कुछ डालने में सक्षम होने के कारण प्रोग्रामर को यह सोचने से मुक्त करता है कि विभिन्न-प्रगति संगणनाओं की स्थिति का कुशलता से प्रतिनिधित्व कैसे करें ताकि उन्हें बाधित किया जा सके और बाद में फिर से शुरू किया जा सके।
एक उदाहरण के रूप में, वीडियो संपीड़न, एक बहुत ही सीपीयू-गहन कार्य पर विचार करें। यदि आप एक gui टूल का उपयोग कर रहे हैं, तो आप चाहते हैं कि इंटरफ़ेस उत्तरदायी बने रहे (प्रगति दिखाएं, अनुरोधों को रद्द करने के लिए जवाब दें, विंडो आकार बदलना, आदि)। इसलिए आप एक समय में एक बड़ी इकाई (एक या अधिक फ़्रेम) को संसाधित करने के लिए अपने एनकोडर सॉफ़्टवेयर को डिज़ाइन करें और इसे अपने स्वयं के धागे में चलाएं, यूआई से अलग।
बेशक एक बार जब आपको एहसास हो जाता है कि इन-प्रोग्रेस एन्कोडिंग स्टेट को बचाने में सक्षम होना अच्छा है, तो आप प्रोग्राम को रिबूट करने या संसाधन-भूखे गेम को बंद करने में सक्षम हो सकते हैं, तो आपको एहसास होता है कि आपको राज्य मशीनों को कैसे डिजाइन करना चाहिए इसकी शुरुआत हुई। या तो आप, या आप अपने OS को प्रोसेस-हाइबरनेशन की पूरी नई इंजीनियर के रूप में तय करते हैं ताकि आप डिस्क पर अलग-अलग ऐप्स को निलंबित और फिर से शुरू कर सकें ...