एक coroutine और एक धागे के बीच अंतर क्या है? क्या एक के ऊपर एक प्रयोग करने के कोई फायदे हैं?
एक coroutine और एक धागे के बीच अंतर क्या है? क्या एक के ऊपर एक प्रयोग करने के कोई फायदे हैं?
जवाबों:
जबकि कोराउटाइन पहली नज़र में धागे की तरह काम करते हैं, वे वास्तव में किसी भी मल्टीथ्रेडिंग का उपयोग नहीं कर रहे हैं। जब तक वे क्रमिक रूप से निष्पादित नहीं होते हैं yield
। इंजन अपने स्वयं के मुख्य लूप के हिस्से के रूप में सभी उपज वाले कोरटाइन की जांच करेगा (बिल्कुल किस बिंदु पर निर्भर करता है yield
, अधिक जानकारी के लिए इस आरेख की जांच करें ), उन्हें अपने अगले तक एक के बाद एक जारी रखें yield
और फिर मुख्य लूप के साथ आगे बढ़ें।
इस तकनीक का यह फायदा है कि आप वास्तविक मल्टीथ्रेडिंग की समस्याओं के कारण होने वाले सिरदर्द के बिना कोरटाइन का उपयोग कर सकते हैं। आपको संदर्भ स्विच के कारण कोई भी गतिरोध, दौड़ की स्थिति या प्रदर्शन की समस्याएं नहीं मिलेंगी, आप ठीक से डिबग कर पाएंगे और आपको थ्रेड-सुरक्षित डेटा कंटेनर का उपयोग करने की आवश्यकता नहीं है। ऐसा इसलिए है क्योंकि जब एक कोरआउट को निष्पादित किया जा रहा है, तो एकता इंजन नियंत्रित स्थिति में है। अधिकांश एकता कार्यक्षमता का उपयोग करना सुरक्षित है।
थ्रेड्स के साथ, दूसरी ओर, आपको इस बारे में बिल्कुल जानकारी नहीं है कि इस समय एकता मुख्य लूप किस स्थिति में है (यह वास्तव में अब बिल्कुल नहीं चल सकता है)। तो आपका धागा एक बार में कुछ ऐसा कर सकता है जो उस चीज़ को करने के लिए नहीं है। उप-थ्रेड से किसी भी मूल एकता कार्यक्षमता को स्पर्श न करें । यदि आपको उप-थ्रेड और आपके मुख्य थ्रेड के बीच संवाद करने की आवश्यकता है, तो थ्रेड को कुछ थ्रेड-सेफ (!) कंटेनर-ऑब्जेक्ट पर लिखें और एक मोनोबेवियर को उस जानकारी को सामान्य एकता ईवेंट फ़ंक्शन के दौरान पढ़ें।
"वास्तविक" मल्टीथ्रेडिंग नहीं करने का नुकसान यह है कि आप कई सीपीयू कोर पर सीपीयू-गहन गणनाओं को समानांतर करने के लिए कोरटाइन का उपयोग नहीं कर सकते हैं। आप कई अद्यतनों पर गणना को विभाजित करने के लिए, हालांकि, उनका उपयोग कर सकते हैं। इसलिए एक सेकंड के लिए अपने गेम को फ्रीज करने के बजाय, आपको बस कई सेकंड्स में कम औसत फ्रैमरेट मिलता है। लेकिन उस स्थिति में आप yield
अपने coroutine के लिए ज़िम्मेदार होते हैं जब भी आप एकता को अपडेट चलाने की अनुमति देना चाहते हैं।
निष्कर्ष:
कॉरटुइन हम कंप्यूटर विज्ञान में कहते हैं "सहकारी मल्टीटास्किंग।" वे प्रत्येक सहकारिता के साथ पारस्परिक रूप से निष्पादन के कई अलग-अलग धाराओं के लिए एक रास्ता हैं। सहकारी मल्टीटास्किंग में निष्पादन की एक धारा में सीपीयू का एकमात्र निर्विवाद स्वामित्व होता है जब तक कि यह एक तक नहीं पहुंच जाता है yield
। उस बिंदु पर, एकता (या जो भी रूपरेखा आप उपयोग कर रहे हैं), निष्पादन की एक अलग धारा में स्विच करने का विकल्प है। यह तब तक सीपीयू का एकमात्र निर्विवाद स्वामित्व प्राप्त करता है जब तक कि यह yield
एस।
थ्रेड्स जिसे हम "प्रीमेप्टिव मल्टीटास्किंग" कहते हैं। जब आप थ्रेड्स का उपयोग कर रहे होते हैं, तो फ्रेम आपके थ्रेड को मध्य-विचार को रोकने और किसी अन्य थ्रेड पर स्विच करने का अधिकार किसी भी समय रखता है । इससे कोई फर्क नहीं पड़ता कि आप कहां हैं। तुम भी कुछ मामलों में स्मृति के लिए एक चर लिखने के माध्यम से भाग रास्ता रोका जा सकता है!
प्रत्येक के लिए पेशेवरों और विपक्ष हैं। कोराउटाइन की समझ शायद सबसे आसान है। सबसे पहले, कोरआउट सभी एक ही कोर पर निष्पादित करते हैं। यदि आपके पास एक क्वाड कोर सीपीयू है, तो कोरटाइन केवल चार कोर में से एक का उपयोग करेगा। यह चीजों को सरल करता है, लेकिन कुछ मामलों में एक प्रदर्शन मुद्दा हो सकता है। दूसरा चोर यह है कि आपको इस बात की जानकारी होनी चाहिए कि कोई भी कोरटाइन आपके पूरे कार्यक्रम को केवल मना करके रोक सकता है yield
। यह कई साल पहले मैक ओएस 9 पर एक मुद्दा था। OS9 ने पूरे कंप्यूटर में केवल सहकारी मल्टीटास्किंग का समर्थन किया। यदि आपका कोई प्रोग्राम लटका हुआ है, तो यह कंप्यूटर को इतनी मजबूती से रोक सकता है कि ओएस आपको त्रुटि संदेश के पाठ को भी प्रस्तुत नहीं कर सकता है ताकि आपको पता चल सके कि क्या हुआ था!
कोरटाइन्स के नियम यह हैं कि वे समझने में अपेक्षाकृत आसान हैं। आपके द्वारा की गई त्रुटियां कहीं अधिक अनुमानित हैं। वे आम तौर पर कम संसाधनों के लिए भी कॉल करते हैं, जो आपके लिए उपयोगी हो सकता है क्योंकि आप 10 के हजारों कोरटाइन या थ्रेड में चढ़ते हैं। उम्मीदवार चंद्रमा ने टिप्पणियों में उल्लेख किया है कि, यदि आपने थ्रेड्स का सही अध्ययन नहीं किया है, तो बस कोरटाइन से चिपके रहते हैं, और वे सही हैं। साथ काम करने के लिए कोरीटीन बहुत सरल हैं।
धागे पूरी तरह से एक अलग जानवर हैं। आपको हमेशा इस संभावना से बचना होगा कि कोई भी धागा किसी भी समय आपको बाधित कर सकता हैऔर अपने डेटा के साथ गड़बड़। थ्रेडिंग लाइब्रेरी आपको इस के साथ सहायता करने के लिए शक्तिशाली उपकरणों के पूरे सूट प्रदान करती है, जैसे म्यूटेक्स और कंडीशन वैरिएबल जो आपको ओएस को यह बताने में मदद करते हैं कि यह आपके अन्य थ्रेड्स में से एक को चलाने के लिए सुरक्षित है और कब असुरक्षित है। इन उपकरणों का अच्छी तरह से उपयोग करने के लिए समर्पित पूरे पाठ्यक्रम हैं। प्रसिद्ध मुद्दों में से एक "गतिरोध" है, जो तब होता है जब दो धागे दोनों "अटक" हो जाते हैं, दूसरे को कुछ संसाधनों को मुक्त करने के लिए इंतजार करते हैं। एक अन्य मुद्दा, जो एकता के लिए बहुत महत्वपूर्ण है, यह है कि कई पुस्तकालयों (जैसे एकता) को कई थ्रेड से कॉल का समर्थन करने के लिए डिज़ाइन नहीं किया गया है। आप बहुत आसानी से अपने ढांचे को तोड़ सकते हैं यदि आप ध्यान नहीं देते हैं कि किन कॉलों की अनुमति है और किन लोगों को मना किया गया है।
इस अतिरिक्त जटिलता का कारण वास्तव में बहुत सरल है। प्रीमेप्टिव मल्टीटास्किंग मॉडल वास्तव में मल्टीथ्रेडिंग मॉडल के समान है जो आपको न केवल अन्य थ्रेड्स को बाधित करने की अनुमति देता है, बल्कि वास्तव में अलग-अलग कोर पर थ्रेड्स को साथ-साथ चलाता है। यह अविश्वसनीय रूप से शक्तिशाली है, वास्तव में इन नए क्वाड कोर और हेक्स कोड सीपीयू का लाभ उठाने का एकमात्र तरीका है जो बाहर आ रहे हैं, लेकिन पैंडोरास बॉक्स खोलते हैं। एक मल्टीथ्रेडिंग दुनिया में इस डेटा को कैसे प्रबंधित किया जाए, इसके लिए सिंक्रनाइज़ेशन नियम सकारात्मक रूप से क्रूर हैं। C ++ की दुनिया में, पूरे लेख समर्पित हैं, MEMORY_ORDER_CONSUME
जो मल्टीथिस सिंक्रोनाइजेशन का एक इट्टी-बिटी-टीन-वेनी कॉर्नर है।
तो थ्रेडिंग की बात? सरल: वे कठिन हैं। आप उन बग के पूरे वर्गों में आ सकते हैं जिन्हें आपने पहले कभी नहीं देखा है। कई तथाकथित "हाइजेनबग्स" होते हैं जो कभी-कभी दिखाई देते हैं, और फिर जब आप उन्हें डिबग करते हैं तो गायब हो जाते हैं। इनसे निपटने के लिए आपको जो उपकरण दिए गए हैं, वे बहुत शक्तिशाली हैं, लेकिन वे बहुत निम्न स्तर के भी हैं। वे आधुनिक चिप्स के आर्किटेक्चर पर कुशल होने के लिए डिज़ाइन किए गए हैं बजाय उपयोग करने के लिए डिज़ाइन किए जाने के लिए।
हालाँकि, यदि आप अपने सभी CPU शक्ति का उपयोग करना चाहते हैं, तो वे आपके लिए आवश्यक उपकरण हैं। इसके अलावा, वहाँ रहे हैं वास्तव में एल्गोरिदम कि multithreading की तुलना में वे coroutines के साथ हैं में समझने के लिए बस क्योंकि आप ओएस संभाल सब जहां रुकावट जगह ले जा सकते हैं के सवाल करते हैं आसान है।
कैंडिनेट्स से चिपके रहने के लिए उम्मीदवार चंद्रमा की टिप्पणी मेरी भी सिफारिश है। यदि आप थ्रेड्स की शक्ति चाहते हैं, तो इसके लिए प्रतिबद्ध हैं। बाहर जाओ और वास्तव में सूत्र सीखो, औपचारिक रूप से। हमारे पास कई दशकों से यह जानने के लिए है कि थ्रेड्स के बारे में सोचने का सबसे अच्छा तरीका कैसे व्यवस्थित किया जाए ताकि आपको जल्दी विश्वसनीय दोहराए जाने वाले परिणाम मिलें, और जैसे ही आप जाते हैं, प्रदर्शन जोड़ें। उदाहरण के लिए, सभी समझदार पाठ्यक्रम हालत चर सिखाने से पहले म्यूटेक्स पढ़ाएंगे। एटमिक्स को कवर करने वाले सभी साने पाठ्यक्रम पूरी तरह से म्यूटेक्स और कंडीशन वैरिएबल्स को सिखाएंगे, यहां तक कि एटमिक्स मौजूद होने का भी उल्लेख करेंगे। (नोट: एटमिक्स पर एक सायन ट्यूटोरियल जैसी कोई बात नहीं है।) थ्रेडिंग टुकड़ा सीखने की कोशिश करें, और आप माइग्रेन के लिए भीख माँग रहे हैं।
join()
, लेकिन आपको कुछ चाहिए। यदि आपके पास एक आर्किटेक्ट नहीं है जो आपके लिए सिंक्रोनाइज़ेशन करने के लिए एक सिस्टम डिज़ाइन करता है, तो आपको खुद को लिखना होगा। जैसा कि कोई ऐसा व्यक्ति है, जो सामानों का उपयोग करता है, मुझे लगता है कि कंप्यूटर के काम करने के लिए लोगों के मानसिक मॉडल को समायोजित करने से पहले उन्हें सुरक्षित रूप से सिंक्रनाइज़ करने की आवश्यकता है (जो कि अच्छे पाठ्यक्रम सिखाएंगे)
join
। मेरा कहना था कि थ्रेडिंग के संभावित प्रदर्शन लाभों का एक मामूली अंश का पीछा करना, आसानी से, कभी-कभी अधिक जटिल थ्रेडिंग दृष्टिकोण का उपयोग करने से बेहतर हो सकता है कि एक बड़े अंश को पुनः प्राप्त करना।
सबसे सरल शब्दों में संभव ...
धागे
जब यह पैदावार होता है तो एक धागा यह तय नहीं करता है कि ऑपरेटिंग सिस्टम ('OS', उदाहरण के लिए Windows) यह तय करता है कि एक धागा कैसे प्राप्त किया जाए। ऑपरेटिंग सिस्टम थ्रेड्स शेड्यूल करने के लिए लगभग पूरी तरह से जिम्मेदार है, यह तय करता है कि उन्हें कौन से थ्रेड्स चलाने हैं, उन्हें कब और कितने समय तक चलाना है।
इसके अतिरिक्त एक धागा सिंक्रोनस (एक के बाद एक धागा) या असिंक्रोनस (अलग-अलग सीपीयू कोर पर चलने वाले अलग-अलग धागे) चलाया जा सकता है। अतुल्यकालिक रूप से चलने की क्षमता का मतलब है कि थ्रेड्स को उसी समय में अधिक काम मिल सकता है (क्योंकि थ्रेड्स शाब्दिक रूप से एक ही समय में दो काम कर रहे हैं)। अगर तुल्यकालन में ओएस अच्छा है, तो भी तुल्यकालिक धागे बहुत काम करते हैं।
हालांकि, यह अतिरिक्त प्रसंस्करण शक्ति दुष्प्रभाव के साथ आती है। उदाहरण के लिए, यदि दो सूत्र एक ही संसाधन (जैसे एक सूची) तक पहुँचने का प्रयास कर रहे हैं और प्रत्येक धागे को कोड के किसी भी बिंदु पर बेतरतीब ढंग से रोका जा सकता है, तो दूसरे धागे के संशोधन पहले धागे द्वारा किए गए संशोधनों में हस्तक्षेप कर सकते हैं। (यह भी देखें: दौड़ की स्थिति और गतिरोध ।)
थ्रेड्स को 'भारी' भी माना जाता है क्योंकि उनके पास बहुत अधिक ओवरहेड होता है, जिसका अर्थ है कि थ्रेड्स स्विच करते समय काफी समय जुर्माना लगाया जाता है।
Coroutines
थ्रेड्स के विपरीत, कोरआउट पूरी तरह से सिंक्रोनस होते हैं, केवल एक कोरआउट किसी भी समय चल सकता है। इसके अलावा, कोरटाइन को चुनने के लिए मिलता है जब उपज होती है, और इस तरह कोड में एक बिंदु पर उपज का चयन कर सकते हैं जो कि आश्वस्त है (जैसे लूप चक्र के अंत में)। इससे दौड़ की स्थिति और गतिरोध से बचने के लिए बहुत आसान मुद्दों के साथ-साथ कोरटाइन के लिए एक दूसरे के साथ सहयोग करना आसान हो जाता है।
हालांकि यह एक बड़ी जिम्मेदारी भी है, अगर कोई कोरटाइन ठीक से उपज नहीं देता है तो यह बहुत अधिक प्रोसेसर समय का उपभोग कर सकता है और यह अभी भी बग का कारण बन सकता है अगर यह साझा संसाधनों को गलत तरीके से संशोधित करता है।
आमतौर पर कोराटाइन को कोई संदर्भ स्विचिंग की आवश्यकता नहीं होती है और इस प्रकार वे अंदर और बाहर स्विच करने के लिए जल्दी होते हैं और काफी हल्के होते हैं।
संक्षेप में:
थ्रेड:
coroutine:
धागे और कोरटाइन की भूमिकाएं बहुत समान हैं, लेकिन वे अलग-अलग हैं कि वे कैसे काम करते हैं, जिसका अर्थ है कि प्रत्येक अलग-अलग कार्यों के लिए बेहतर है। थ्रेड्स उन कार्यों के लिए सबसे अच्छे हैं जहां वे बिना रुकावट के अपने दम पर कुछ करने पर ध्यान केंद्रित कर सकते हैं, फिर जब वे काम कर रहे होते हैं तो वापस संकेत देते हैं। कोराटाइन उन कार्यों के लिए सबसे अच्छा है जो बहुत से छोटे चरणों में किए जा सकते हैं और ऐसे कार्य जिन्हें सहकारी प्रसंस्करण डेटा की आवश्यकता होती है।