मल्टीथ्रेडिंग: कोर की तुलना में अधिक थ्रेड्स का क्या मतलब है?


142

मुझे लगा कि मल्टी-कोर कंप्यूटर की बात यह है कि यह एक साथ कई थ्रेड चला सकता है। उस स्थिति में, यदि आपके पास क्वाड-कोर मशीन है, तो एक बार में 4 से अधिक धागे होने की क्या बात है? क्या वे सिर्फ एक-दूसरे से समय (CPU संसाधन) नहीं चुरा रहे होंगे?


52
हम इस प्रकार के प्रश्नों का आनंद लेते हैं, वे किसी चीज़ के बहुत मौलिक होने पर सवाल उठाते हैं, जो कि लिया जाता
है..जिसके लिए

6
आपके क्वाड कोर मशीन पर फ़ायरफ़ॉक्स, एमएस वर्ड, विनैंप, एक्लिप्स और एक डाउनलोड मैनेजर (चार से अधिक प्रोग्राम / प्रक्रियाएं) एक साथ कब चल रहे थे? इसके अलावा, एक एकल अनुप्रयोग कभी-कभी चार थ्रेड से अधिक हो सकता है - इसके बारे में कैसे?
अमरघोष

1
चोरी करना जरूरी बुरा नहीं है। आपके पास महत्वपूर्ण कार्यों के लिए एक उच्च प्राथमिकता के साथ एक धागा हो सकता है जिसे समय चुराने की आवश्यकता होती है।
किचिक

1
@Amarghosh मुझे लगता है कि सवाल था, क्यों एकल अनुप्रयोग कोर से अधिक धागे स्पॉन करना चाह सकता है अगर यह कोई प्रदर्शन लाभ नहीं लाता है। और चार से अधिक कार्यक्रमों के साथ आपका उदाहरण यहां काफी प्रासंगिक नहीं है। जैसा कि आपने सही ढंग से नोट किया, वे प्रक्रियाएं हैं। OS मल्टीटास्किंग सुविधा (प्रोसेस मल्टीप्लेक्सिंग) का एक प्रक्रिया के भीतर थ्रेड से बहुत कम संबंध है।
Mar१

जवाबों:


81

उत्तर धागे के उद्देश्य के आसपास घूमता है, जो समानता है: एक ही बार में निष्पादन की कई अलग-अलग लाइनें चलाने के लिए। एक 'आदर्श' प्रणाली में, आपके पास प्रति कोर एक धागा निष्पादन होगा: कोई रुकावट नहीं। वास्तव में यह मामला नहीं है। यहां तक ​​कि अगर आपके पास चार कोर और चार काम करने वाले धागे हैं, तो आपकी प्रक्रिया और यह धागे लगातार अन्य प्रक्रियाओं और थ्रेड्स के लिए स्विच किए जाएंगे। यदि आप कोई आधुनिक ओएस चला रहे हैं, तो हर प्रक्रिया में कम से कम एक धागा है, और कई में अधिक है। ये सभी प्रक्रियाएं एक ही बार में चल रही हैं। आपके पास अभी कई सौ धागे हैं जो अभी आपकी मशीन पर चल रहे हैं। आपको कभी भी ऐसी स्थिति नहीं मिलेगी जहां कोई थ्रेड बिना समय के 'चोरी' से चलता हो। (ठीक है, आप अगर यह वास्तविक समय चल रहा है हो सकता है, अगर आप एक realtime OS का उपयोग कर रहे हैं या, यहां तक ​​कि विंडोज पर भी, एक रीयल-टाइम थ्रेड प्राथमिकता का उपयोग करें। लेकिन यह दुर्लभ है।)

उस पृष्ठभूमि के साथ, उत्तर: हां, एक सच्चे चार-कोर मशीन पर चार से अधिक धागे आपको एक ऐसी स्थिति दे सकते हैं, जहां वे 'एक दूसरे से समय चुराते हैं', लेकिन केवल अगर प्रत्येक व्यक्ति को 100% सीपीयू की आवश्यकता होती है । यदि कोई थ्रेड 100% काम नहीं कर रहा है (जैसा कि यूआई थ्रेड नहीं हो सकता है, या एक थ्रेड थोड़ी मात्रा में काम कर रहा है या किसी और चीज़ पर प्रतीक्षा कर रहा है) तो एक और थ्रेड अनुसूचित होना वास्तव में एक अच्छी स्थिति है।

यह वास्तव में उससे अधिक जटिल है:

  • क्या होगा अगर आपके पास काम के पांच बिट्स हैं जो सभी को एक बार में करने की आवश्यकता है? यह उन सभी को एक साथ चलाने के लिए अधिक समझ में आता है, उनमें से चार को चलाने के लिए और फिर बाद में पांचवें को चलाने के लिए।

  • यह वास्तव में 100% सीपीयू के लिए एक धागे के लिए दुर्लभ है। जिस क्षण यह डिस्क या नेटवर्क I / O का उपयोग करता है, उदाहरण के लिए, यह संभावित रूप से समय व्यतीत कर सकता है जो कुछ भी उपयोगी नहीं है। यह एक बहुत ही सामान्य स्थिति है।

  • यदि आपके पास काम है जिसे चलाने की आवश्यकता है, तो एक सामान्य तंत्र एक थ्रेडपूल का उपयोग करना है। यह कोर के रूप में धागे की एक ही संख्या के लिए समझ बनाने के लिए लग सकता है, फिर भी .net थ्रेडपूल में 250 प्रोसेसर तक उपलब्ध धागे हैं । मुझे यकीन नहीं है कि वे ऐसा क्यों करते हैं, लेकिन मेरा अनुमान उन कार्यों के आकार के साथ करना है जो थ्रेड्स पर चलने के लिए दिए गए हैं।

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


16
+1 के लिए "लेकिन केवल अगर प्रत्येक व्यक्ति को 100% सीपीयू की आवश्यकता हो"। यह धारणा थी कि मुझे एहसास नहीं था कि मैं बना रहा हूं।
निक हेइनर

1
एक बेहतरीन सवाल का शानदार जवाब। धन्यवाद!
एजुकैस

53

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

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


11
ख़ूब कहा है। 'CPU प्रति एक धागा' तर्क केवल CPU-बाउंड कोड पर लागू होता है। एसिंक्रोनस प्रोग्रामिंग थ्रेड्स का उपयोग करने का एक और कारण है।
जोशुआ डेविस

26

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

यहां तक ​​कि एक मामूली जटिल अनुप्रयोग में, एक ही धागे का उपयोग करके सब कुछ जल्दी से करने की कोशिश करना आपके कोड के 'प्रवाह' का हैश बनाता है। एकल धागा अपना अधिकांश समय इस पर खर्च करने, उस पर जाँच करने, आवश्यकतानुसार सशर्त रूप से रूटीन कॉल करने में बिताता है, और यह कुछ भी देखना मुश्किल हो जाता है, लेकिन माइनुटिया की नैतिकता।

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

इस तरह से काम को विभाजित करने से आपके आवेदन को सीपीयू के साथ आगे क्या करना है, यह निर्धारित करने के लिए ऑपरेटिंग सिस्टम पर भरोसा करने की अनुमति मिलती है, इसलिए आपको अपने आवेदन में हर जगह स्पष्ट सशर्त जांच करने की आवश्यकता नहीं है कि क्या हो सकता है और क्या प्रक्रिया के लिए तैयार है।


1
यह एक दिलचस्प विचार है ... मैंने हमेशा सुना होगा कि एक ऐप को मल्टीथ्रेडिंग करना जटिलता का शुद्ध जोड़ है, लेकिन आप जो कह रहे हैं वह समझ में आता है।
निक हेइनर

यदि किसी व्यक्ति की चिंताएँ पर्याप्त रूप से अलग नहीं की जाती हैं, तो ऐप को मल्टीप्लेडिंग करने से जटिलता बढ़ जाती है। यदि यह चिंताओं के न्यूनतम ओवरलैप (और इस तरह साझा की गई स्थिति) के साथ डिज़ाइन किया गया है तो यह जटिलता के मुद्दों में एक शुद्ध बचत है।
JUST MY सही ओपिनियन

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

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

15

यदि कोई थ्रेड किसी संसाधन की प्रतीक्षा कर रहा है (जैसे 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 और अन्य विवरणों का मुख्य भाग पहले से ही रजिस्टरों में लोड किए गए मानों का उपयोग करता है, तो प्रोसेसर स्थिति का मूल्यांकन करने से पहले एक या दोनों शाखाओं को निष्पादित कर सकता है। एक बार स्थिति वापस आने पर, प्रोसेसर संबंधित शाखा के परिणाम को लागू करेगा और दूसरे को छोड़ देगा। यहां संभावित रूप से बेकार काम करना संभवतः एक अलग धागे पर स्विच करने से बेहतर है, जिससे थ्रैशिंग हो सकती है।

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


एक ही धागे और एक कतार के साथ किया जा सकता है: \ _ क्या वास्तव में 2-4 कोर पर 80 धागे होने का कोई लाभ है, बस 2-4 कोर होने पर, जो आते ही कतार से अलग काम करते हैं। और उनके पास करने के लिए कुछ नहीं है?
दिमित्री

8

ऊपर दिए गए अधिकांश उत्तर प्रदर्शन और एक साथ संचालन के बारे में बात करते हैं। मैं इसे एक अलग कोण से देखने जा रहा हूँ।

चलो, एक सरलीकृत टर्मिनल अनुकरण कार्यक्रम के मामले को कहते हैं। आपको निम्नलिखित काम करने होंगे:

  • रिमोट सिस्टम से आने वाले पात्रों के लिए देखें और उन्हें प्रदर्शित करें
  • कीबोर्ड से आने वाले सामान के लिए देखें और उन्हें रिमोट सिस्टम पर भेजें

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

अब दूरस्थ से पढ़ने के लिए लूप सरल है, निम्न सूडोकोड के अनुसार:

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-बाध्य हैं, तो थ्रेडिंग वास्तव में आपके सिस्टम को धीमा कर देती है। प्रदर्शन से नुकसान होगा। बहुत, कई मामलों में। ("थ्रैशिंग" एक सामान्य समस्या है यदि आप बहुत अधिक सीपीयू-बाउंड थ्रेड्स को छोड़ देते हैं। आप थ्रेड्स की सामग्री को स्वयं चलाने की तुलना में सक्रिय थ्रेड्स को बदलने में अधिक समय व्यतीत करते हैं।) इसके अलावा, ऊपर दिए गए तर्क के कारणों में से एक है। इतना सरल है कि मैंने बहुत जानबूझकर एक सरलीकृत (और अवास्तविक) उदाहरण चुना है। यदि आप स्क्रीन पर टाइप किया गया गूंज चाहते थे तो आपको साझा संसाधनों की लॉकिंग शुरू करने के साथ चोट की एक नई दुनिया मिल गई है। केवल एक साझा संसाधन के साथ यह इतनी समस्या नहीं है, लेकिन यह एक बड़ी और बड़ी समस्या बनने लगती है क्योंकि आपके पास साझा करने के लिए अधिक संसाधन हैं।

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


6

यद्यपि आप निश्चित रूप से अपने हार्डवेयर के आधार पर गणना में तेजी लाने के लिए थ्रेड्स का उपयोग कर सकते हैं, उनका मुख्य उपयोग उपयोगकर्ता-मित्रता कारणों से एक समय में एक से अधिक काम करना है।

उदाहरण के लिए, यदि आपको पृष्ठभूमि में कुछ प्रसंस्करण करना है और यूआई इनपुट के लिए भी उत्तरदायी है, तो आप थ्रेड का उपयोग कर सकते हैं। थ्रेड्स के बिना, उपयोगकर्ता इंटरफ़ेस हर बार आपके द्वारा किसी भी भारी प्रसंस्करण को करने की कोशिश करने पर लटका होगा।

इस संबंधित प्रश्न को भी देखें: थ्रेड्स के लिए व्यावहारिक उपयोग


UI हैंडलिंग IO- बाउंड कार्य का एक उत्कृष्ट उदाहरण है। प्रसंस्करण और IO दोनों कार्यों में एक ही CPU कोर का होना अच्छा नहीं है।
डोनाल्ड फेलो

6

मैं @ kyoryu के जोर से असहमत हूं कि आदर्श संख्या प्रति CPU एक धागा है।

इसके बारे में इस तरह से सोचें: हमारे पास मल्टी-प्रोसेसिंग ऑपरेटिंग सिस्टम क्यों है? अधिकांश कंप्यूटर इतिहास के लिए, लगभग सभी कंप्यूटरों में एक CPU था। फिर भी 1960 के दशक से, सभी "वास्तविक" कंप्यूटरों में मल्टी-प्रोसेसिंग (उर्फ मल्टी-टास्किंग) ऑपरेटिंग सिस्टम था।

आप कई प्रोग्राम चलाते हैं ताकि कोई चला सके जबकि अन्य आईओ जैसी चीजों के लिए अवरुद्ध हो।

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

थ्रेड्स ऐसे कार्य हैं जो थोड़े अधिक कुशल हैं। किसी कार्य, प्रक्रिया और धागे के बीच कोई बुनियादी अंतर नहीं है।

एक सीपीयू बर्बाद करने के लिए एक भयानक चीज है, इसलिए जब आप यह कर सकते हैं तो बहुत सारी चीजें इसका उपयोग करने के लिए तैयार हैं।

मैं इस बात से सहमत हूँ कि अधिकांश प्रक्रियात्मक भाषाओं, C, C ++, Java आदि के साथ, उचित थ्रेड सेफ कोड लिखना बहुत काम का है। आज बाजार पर 6 कोर सीपीयू के साथ, और 16 कोर सीपीयू दूर नहीं हैं, मुझे उम्मीद है कि लोग इन पुरानी भाषाओं से दूर हो जाएंगे, क्योंकि मल्टी-थ्रेडिंग एक महत्वपूर्ण आवश्यकता से अधिक है।

@Kyoryu से असहमति सिर्फ IMHO है, बाकी तथ्य यह है।


5
यदि आपने बहुत सारे प्रोसेसर-बाउंड थ्रेड प्राप्त किए हैं, तो आदर्श संख्या प्रति सीपीयू (या शायद एक कम है, सभी को आई / ओ और ओएस और उस सभी सामान को प्रबंधित करने के लिए छोड़ना है)। यदि आपको IO- बाउंड थ्रेड्स मिले हैं, तो आप एक CPU पर बहुत अधिक स्टैक कर सकते हैं। विभिन्न ऐप्स में प्रोसेसर-बाउंड और IO- बाउंड कार्यों के अलग-अलग मिक्स होते हैं; यह पूरी तरह से स्वाभाविक है, लेकिन आपको सार्वभौमिक घोषणाओं से सावधान रहना होगा।
डोनल फेलो

1
बेशक, थ्रेड्स और प्रक्रियाओं के बीच सबसे महत्वपूर्ण अंतर यह है कि विंडोज पर कोई कांटा () नहीं है, इसलिए प्रक्रिया निर्माण वास्तव में महंगा है, थ्रेड्स के उपयोग के लिए अग्रणी है।
नंजाल

प्रोटीन फोल्डिंग, SETI आदि को छोड़कर, कोई व्यावहारिक उपयोगकर्ता कार्य नहीं हैं जो बहुत लंबे समय तक बाध्य हैं। हमेशा उपयोगकर्ता से जानकारी प्राप्त करने की आवश्यकता होती है, डिस्क पर बात करते हैं, DBMS से बात करते हैं, आदि। हाँ, कांटा की कीमत () कई चीजों में से एक है जो कटलर ने NT को शाप दिया था कि DEC में अन्य लोग जानते थे।
23 अगस्त को फिशटॉपसर्कॉर्ड्स

5

एक वेब सर्वर की कल्पना करें, जिसे कई मनमाने अनुरोधों को पूरा करना है। आपको अनुरोधों को समानांतर रूप से सेवा करनी होगी क्योंकि अन्यथा प्रत्येक नए अनुरोध को तब तक इंतजार करना होगा जब तक कि अन्य सभी अनुरोधों को पूरा नहीं किया जाता है (इंटरनेट पर प्रतिक्रिया भेजने सहित)। इस मामले में, अधिकांश वेब सर्वरों के पास अनुरोधों की संख्या की तुलना में कम कोर होते हैं जो वे आमतौर पर सेवा करते हैं।

यह सर्वर के डेवलपर के लिए भी आसान बनाता है: आपको केवल एक थ्रेड प्रोग्राम लिखना होगा जो एक अनुरोध पर काम करता है, आपको कई अनुरोधों को संग्रहीत करने के बारे में सोचने की ज़रूरत नहीं है, जिस क्रम में आप उनकी सेवा करते हैं, और इसी तरह।


2
आप एक ऑपरेशन सिस्टम के लिए सॉफ्टवेयर लिख रहे हैं जो थ्रेडिंग का समर्थन करता है लेकिन इसमें io को मल्टीप्लेक्स करने की क्षमता नहीं है? मुझे लगता है कि वेब सर्वर शायद एक बुरा उदाहरण है क्योंकि इस मामले में मल्टीप्लेक्सिंग io लगभग हमेशा कोर से अधिक थ्रेड्स को थूकने की तुलना में अधिक कुशल होने वाला है।
जेसन कोको

3

कई धागे सो रहे होंगे, उपयोगकर्ता इनपुट, I / O, और अन्य घटनाओं की प्रतीक्षा कर रहे हैं।


पक्का। बस असली ओएस पर विंडोज या टॉप पर टास्क मैनेजर का उपयोग करें, और देखें कि कितने कार्य / प्रक्रियाएं अलसीप हैं। इसका हमेशा 90% या उससे अधिक।
23 अगस्त को फिशटॉपसर्कॉर्ड्स

2

थ्रेड यूआई अनुप्रयोगों में जवाबदेही के साथ मदद कर सकते हैं। इसके अतिरिक्त, आप अपने कोर से अधिक काम पाने के लिए थ्रेड्स का उपयोग कर सकते हैं। उदाहरण के लिए, एक कोर पर, आप एक थ्रेड IO कर सकते हैं और दूसरा कुछ गणना कर सकते हैं। यदि यह सिंगल थ्रेडेड था, तो कोर अनिवार्य रूप से आइओ के पूरा होने के इंतजार में बेकार हो सकता है। यह एक उच्च स्तरीय उदाहरण है, लेकिन थ्रेड्स का उपयोग निश्चित रूप से आपके सीपीयू को थोड़ा कठिन बनाने के लिए किया जा सकता है।


अधिक विशेष रूप से, एक धागा I / O पर प्रतीक्षा कर सकता है जबकि दूसरा गणना करता है। यदि I / O ने (महत्वपूर्ण) सीपीयू चक्र लिया, तो इसे अलग थ्रेड में चलाने का कोई लाभ नहीं होगा। लाभ यह है कि आपका कम्प्यूटेशन थ्रेड चल सकता है जबकि आपका I / O थ्रेड अपने अंगूठे को एक बड़े एल्यूमीनियम सिलेंडर की प्रतीक्षा कर रहा है ताकि वह जगह से बाहर हो सके, या पैकेट से आइसलैंड पर या जो भी हो।
केन

2

प्रोसेसर, या सीपीयू, भौतिक चिप है जिसे सिस्टम में प्लग किया जाता है। एक प्रोसेसर में कई कोर हो सकते हैं (एक कोर चिप का हिस्सा है जो निर्देशों को निष्पादित करने में सक्षम है)। ऑपरेटिंग सिस्टम को कई वर्चुअल प्रोसेसर के रूप में दिखाया जा सकता है यदि यह एक साथ कई थ्रेड्स निष्पादित करने में सक्षम है (एक थ्रेड निर्देशों का एकल अनुक्रम है)।

एक प्रक्रिया एक आवेदन के लिए दूसरा नाम है। आम तौर पर, प्रक्रियाएं एक-दूसरे से स्वतंत्र होती हैं। यदि एक प्रक्रिया मर जाती है, तो यह दूसरी प्रक्रिया भी नहीं मरती है। प्रक्रियाओं के लिए यह संभव है कि वे स्मृति या I / O जैसे संसाधनों को साझा करें या साझा करें।

प्रत्येक प्रक्रिया का एक अलग पता स्थान और स्टैक होता है। एक प्रक्रिया में कई थ्रेड्स हो सकते हैं, प्रत्येक एक साथ निर्देशों को निष्पादित करने में सक्षम होते हैं। एक प्रक्रिया में सभी थ्रेड्स समान पता स्थान साझा करते हैं, लेकिन प्रत्येक थ्रेड का अपना स्टैक होगा।

उम्मीद है कि इन मूल सिद्धांतों का उपयोग करके इन परिभाषाओं और आगे के शोध से आपकी समझ में मदद मिलेगी।


2
मैं यह नहीं देखता कि यह उनके प्रश्न को कैसे संबोधित करता है। उनके प्रश्न की मेरी व्याख्या कोर के धागे के उपयोग और उपलब्ध संसाधनों के इष्टतम उपयोग के बारे में, या धागे के व्यवहार के बारे में है क्योंकि आप उनकी संख्या में वृद्धि करते हैं, या उन रेखाओं के साथ कुछ भी।
डेविड

@ डेविड शायद यह मेरे सवाल का सीधा जवाब नहीं था, लेकिन मुझे अभी भी लगता है कि मैंने इसे पढ़कर सीखा।
निक हेनेर

1

धागे का आदर्श उपयोग, वास्तव में, प्रति कोर एक है।

हालाँकि, जब तक आप विशेष रूप से अतुल्यकालिक / गैर-अवरुद्ध IO का उपयोग नहीं करते हैं, तब तक एक अच्छा मौका है कि आपके पास कुछ बिंदु पर IO पर अवरुद्ध धागे होंगे, जो आपके CPU का उपयोग नहीं करेगा।

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


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

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

@ निक बास्टिन: दुर्भाग्य से, जैसा कि मैंने मुख्य उत्तर में कहा, अधिकांश आधुनिक भाषाएं आसानी से एक प्रणाली को आसानी से लागू करने के लिए खुद को उधार नहीं देती हैं जो यह प्रभावी रूप से तुच्छ नहीं है - आप भाषा के विशिष्ट उपयोग से लड़ने की कुछ मात्रा को समाप्त करते हैं।
कियूरू

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

@ निक बास्टिन: तो, संक्षेप में, एक प्रति कोर धागा आदर्श है, लेकिन वास्तव में इसे प्राप्त करना बहुत संभावना नहीं है। मुझे शायद 'कुछ मुश्किल' से ज्यादा मजबूत होना चाहिए था, जब इस बात की संभावना थी कि वास्तव में इस तरह की चीज हासिल करना कितना मुश्किल है।
कायरू

1

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

आमतौर पर यह एक समस्या नहीं है, हालांकि (यदि यह एक समस्या है, तो ओएस या एपीआई को वैकल्पिक एसिंक्रोनस ऑपरेटिंग मोड के साथ जहाज करना चाहिए, अर्थात:) select(2), क्योंकि इसका मतलब है कि धागा I / के इंतजार में सो रहा होगा / ओ पूरा करना। दूसरी ओर, अगर कुछ एक भारी गणना कर रहा है, आप के लिए है एक अलग थ्रेड में कहते हैं की तुलना में यह डाल करने के लिए, जीयूआई धागा (जब तक आप मैन्युअल बहुसंकेतन का आनंद)।


1

मुझे पता है कि यह एक सुपर पुराना सवाल है जिसमें बहुत सारे अच्छे उत्तर हैं, लेकिन मैं यहां कुछ ऐसा बता रहा हूं जो वर्तमान परिवेश में महत्वपूर्ण है:

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


0

आपके पहले अनुमान के जवाब में: मल्टी-कोर मशीनें एक साथ कई प्रक्रियाएँ चला सकती हैं, न कि किसी एकल प्रक्रिया के कई सूत्र।

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

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


-5

एक धागा एक अमूर्तता है जो आपको ऑपरेशन के अनुक्रम के रूप में सरल रूप से कोड लिखने में सक्षम बनाता है, इस बात से अनजान है कि कोड को अन्य कोड के साथ इंटरलेक्ट किया गया है, या आईओ के इंतजार में खड़ी है, या (शायद कुछ अधिक जागरूक) अन्य थ्रेड के इंतजार में घटनाओं या संदेश।


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

-8

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

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

बेशक एक बार जब आपको एहसास हो जाता है कि इन-प्रोग्रेस एन्कोडिंग स्टेट को बचाने में सक्षम होना अच्छा है, तो आप प्रोग्राम को रिबूट करने या संसाधन-भूखे गेम को बंद करने में सक्षम हो सकते हैं, तो आपको एहसास होता है कि आपको राज्य मशीनों को कैसे डिजाइन करना चाहिए इसकी शुरुआत हुई। या तो आप, या आप अपने OS को प्रोसेस-हाइबरनेशन की पूरी नई इंजीनियर के रूप में तय करते हैं ताकि आप डिस्क पर अलग-अलग ऐप्स को निलंबित और फिर से शुरू कर सकें ...


7
नहीं (काफी!) 1 के लायक है, लेकिन गंभीरता से, कि मैं इस विषय पर किसी को भी कहते हुए सुना है सबसे मूर्खतापूर्ण बात के बारे में है। उदाहरण के लिए, मुझे राज्य मशीन को लागू करने में कोई समस्या नहीं है। बिलकुल भी नहीं। जब अन्य उपकरण वहां होते हैं तो मैं उनका उपयोग करना पसंद नहीं करता, जो कोड को बनाए रखने के लिए स्पष्ट और आसान को पीछे छोड़ देते हैं । राज्य मशीनों के अपने स्थान होते हैं, और उन स्थानों पर जिनका मिलान नहीं किया जा सकता है। GUI अपडेट के साथ CPU-गहन संचालन को इंटरलेस करना उन स्थानों में से एक नहीं है। बहुत कम कोरआउट्स वहां बेहतर विकल्प हैं, जिसमें थ्रेडिंग और भी बेहतर है।
JUST MY सही ओपिनियन

हर कोई मेरे जवाब को कम करने के लिए, यह धागे का उपयोग करने के खिलाफ एक तर्क नहीं है! यदि आप एक राज्य मशीन को कोड कर सकते हैं जो बहुत बढ़िया है, और सुनिश्चित करें कि यह अक्सर अलग-अलग थ्रेड्स में राज्य मशीनों को चलाने के लिए समझ में आता है, भले ही आपके पास न हो। मेरी टिप्पणी थी कि अक्सर थ्रेड्स का उपयोग करने का विकल्प मुख्य रूप से राज्य मशीनों को डिजाइन करने से बचने की इच्छा से बना होता है, जो कई प्रोग्रामर किसी भी अन्य लाभ के बजाय "बहुत कठिन" मानते हैं।
आर .. गिटहब स्टॉप हेल्पिंग ICE
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.