जबकि धागे कोड के निष्पादन को गति दे सकते हैं, क्या वास्तव में उनकी आवश्यकता है? क्या हर एक कोड का उपयोग एक ही धागे से किया जा सकता है या क्या ऐसा कुछ मौजूद है जो केवल कई धागों का उपयोग करके पूरा किया जा सकता है?
जबकि धागे कोड के निष्पादन को गति दे सकते हैं, क्या वास्तव में उनकी आवश्यकता है? क्या हर एक कोड का उपयोग एक ही धागे से किया जा सकता है या क्या ऐसा कुछ मौजूद है जो केवल कई धागों का उपयोग करके पूरा किया जा सकता है?
जवाबों:
सबसे पहले, धागे कोड के निष्पादन को गति नहीं दे सकते हैं। वे कंप्यूटर को तेज नहीं चलाते हैं। वे सभी कर सकते हैं समय का उपयोग करके कंप्यूटर की दक्षता को बढ़ाएं जो अन्यथा बर्बाद हो जाएंगे। कुछ प्रकार के प्रसंस्करण में यह अनुकूलन दक्षता बढ़ा सकता है और चलने के समय को कम कर सकता है।
सरल उत्तर है हां। आप किसी भी कोड को एक धागे पर चलाने के लिए लिख सकते हैं। प्रमाण: एक एकल प्रोसेसर सिस्टम केवल निर्देश रैखिक रूप से चला सकता है। निष्पादन की कई पंक्तियाँ होने से ऑपरेटिंग सिस्टम प्रोसेसिंग में व्यवधान होता है, जिससे वर्तमान थ्रेड की स्थिति बचती है, और एक और शुरू होती है।
जटिल जवाब ... और अधिक जटिल है! बहुदलीय कार्यक्रम अक्सर लीनियर की तुलना में अधिक कुशल हो सकते हैं क्योंकि इसका कारण हार्डवेयर "समस्या" है। CPU मेमोरी और हार्ड स्टोरेज IO की तुलना में अधिक तेजी से गणना निष्पादित कर सकता है। इसलिए, एक "जोड़ें" निर्देश, उदाहरण के लिए, एक "भ्रूण" की तुलना में कहीं अधिक तेज़ी से निष्पादित होता है। कैश और समर्पित कार्यक्रम निर्देश प्राप्त करना (सटीक शब्द यहां निश्चित नहीं है) कुछ हद तक इसका मुकाबला कर सकता है, लेकिन गति मुद्दा बना हुआ है।
थ्रेडिंग इस बेमेल को सीपीयू सीपीयू के लिए सीपीयू का उपयोग करके बाध्य करने का एक तरीका है जबकि आईओ निर्देश पूरा कर रहे हैं। एक विशिष्ट थ्रेड निष्पादन योजना संभवतः होगी: डेटा प्राप्त करें, डेटा संसाधित करें, डेटा लिखें। मान लें कि चित्रण और लेखन में 3 चक्र लगते हैं और प्रसंस्करण एक, उदाहरण के लिए होता है। आप देख सकते हैं कि कंप्यूटर पढ़ते या लिखते समय यह 2 चक्रों के लिए कुछ नहीं कर रहा है ? स्पष्ट रूप से यह आलसी हो रहा है, और हमें अपने अनुकूलन कोड़ा को फोड़ना होगा!
हम इस बर्बाद समय का उपयोग करने के लिए थ्रेडिंग का उपयोग करके प्रक्रिया को फिर से लिख सकते हैं:
और इसी तरह। जाहिर है कि यह कुछ हद तक विरोधाभासी उदाहरण है, लेकिन आप देख सकते हैं कि यह तकनीक उस समय का कैसे उपयोग कर सकती है जो अन्यथा आईओ के इंतजार में बिताया जाएगा।
ध्यान दें कि ऊपर दिखाए गए अनुसार थ्रेडिंग केवल भारी IO बाध्य प्रक्रियाओं पर दक्षता बढ़ा सकती है। यदि कोई कार्यक्रम मुख्य रूप से चीजों की गणना कर रहा है, तो बहुत सारे "छेद" नहीं होंगे, हम इसमें और अधिक काम कर सकते हैं। इसके अलावा, थ्रेड्स के बीच स्विच करते समय कई निर्देशों का ओवरहेड होता है। यदि आप बहुत सारे थ्रेड चलाते हैं, तो सीपीयू ज्यादातर समय स्विच करने में खर्च करेगा और वास्तव में समस्या पर काम नहीं करेगा। इसे थ्रशिंग कहते हैं ।
सिंगल कोर प्रोसेसर के लिए यह सब ठीक है और अच्छा है, लेकिन अधिकांश आधुनिक प्रोसेसर में दो या दो से अधिक कोर होते हैं। थ्रेड्स अभी भी एक ही उद्देश्य पर काम करते हैं - CPU उपयोग को अधिकतम करने के लिए, लेकिन इस बार हमारे पास एक ही समय में दो अलग-अलग निर्देश चलाने की क्षमता है । यह चल रहे समय को कम कर सकता है, हालांकि कई कोर उपलब्ध हैं, क्योंकि कंप्यूटर वास्तव में मल्टीटास्किंग है, संदर्भ स्विचिंग नहीं।
कई कोर के साथ, थ्रेड्स दोनों कोर के बीच विभाजन कार्य की एक विधि प्रदान करते हैं। उपरोक्त अभी भी प्रत्येक व्यक्तिगत कोर के लिए लागू होता है; एक प्रोग्राम जो एक कोर पर दो थ्रेड्स के साथ अधिकतम दक्षता चलाता है, संभवतः दो कोर पर लगभग चार थ्रेड्स के साथ चरम दक्षता पर चलेगा। (दक्षता को न्यूनतम एनओपी अनुदेश निष्पादन द्वारा यहां मापा जाता है।)
एकाधिक कोर (एक कोर के विपरीत) पर चलने वाले थ्रेड्स के साथ समस्याओं का आमतौर पर हार्डवेयर द्वारा ध्यान रखा जाता है। सीपीयू यह सुनिश्चित करेगा कि यह पढ़ने / लिखने से पहले उपयुक्त मेमोरी लोकेशन को लॉक कर दे। (मैंने पढ़ा है कि यह इसके लिए मेमोरी में एक विशेष फ़्लैग बिट का उपयोग करता है, लेकिन इसे कई तरीकों से पूरा किया जा सकता है।) उच्च स्तर की भाषाओं के साथ एक प्रोग्रामर के रूप में, आपको दो कोर पर कुछ भी चिंता करने की ज़रूरत नहीं है। एक के साथ होगा।
टीएल; डीआर: थ्रेड्स काम को विभाजित कर सकते हैं जिससे कंप्यूटर को अतुल्यकालिक रूप से कई कार्यों को संसाधित करने की अनुमति मिलती है। यह किसी संसाधन के लिए प्रतीक्षा कर रहा है जब लॉकिंग के बजाय उपलब्ध सभी संसाधन समय का उपयोग करके कंप्यूटर को अधिकतम दक्षता पर चलाने की अनुमति देता है।
कई धागे क्या कर सकते हैं कि एक भी धागा नहीं हो सकता है?
कुछ भी तो नहीं।
सरल सबूत स्केच:
ध्यान दें, हालांकि, वहाँ एक बड़ी धारणा छिपी हुई है: अर्थात् कि एक सूत्र के भीतर प्रयुक्त भाषा ट्यूरिंग-पूर्ण है।
इसलिए, अधिक दिलचस्प सवाल यह होगा: "क्या नॉन-ट्यूरिंग-पूरी भाषा में सिर्फ मल्टी-थ्रेडिंग को जोड़ने से यह ट्यूरिंग-पूर्ण हो सकता है?" और मुझे विश्वास है, जवाब "हाँ" है।
आइए टोटल फंक्शनल लैंग्वेज लें। [उन लोगों के लिए जो परिचित नहीं हैं: जैसे फ़ंक्शनल प्रोग्रामिंग प्रोग्रामिंग फ़ंक्शंस के साथ है, टोटल फ़ंक्शनल प्रोग्रामिंग प्रोग्रामिंग फ़ंक्शनल है।
टोटल फंक्शनल लैंग्वेज स्पष्ट रूप से ट्यूरिंग-पूर्ण नहीं हैं: आप TFPL में एक अनंत लूप नहीं लिख सकते हैं (वास्तव में, "कुल" की परिभाषा बहुत ज्यादा है ), लेकिन आप ट्यूरिंग मशीन में कर सकते हैं , एर्गो कम से कम एक प्रोग्राम में मौजूद है एक TFPL में नहीं लिखा जा सकता है, लेकिन एक UTM में हो सकता है, इसलिए TFPL, UTM की तुलना में कम कम्प्यूटेशनल रूप से शक्तिशाली होते हैं।
हालांकि, जैसे ही आप एक TFPL में थ्रेडिंग जोड़ते हैं, आपको अनंत लूप मिलते हैं: बस लूप के प्रत्येक पुनरावृत्ति को एक नए धागे में करते हैं। प्रत्येक व्यक्तिगत धागा हमेशा एक परिणाम देता है, इसलिए यह कुल है, लेकिन हर धागा एक नया धागा भी पैदा करता है जो अगले पुनरावृत्ति, विज्ञापन infinitum को निष्पादित करता है ।
मुझे लगता है कि यह भाषा ट्यूरिंग-पूर्ण होगी।
बहुत कम से कम, यह मूल प्रश्न का उत्तर देता है:
कई धागे क्या कर सकते हैं कि एक भी धागा नहीं हो सकता है?
यदि आपके पास एक भाषा है जो अनंत लूप नहीं कर सकती है, तो मल्टी-थ्रेडिंग आपको अनंत लूप करने की अनुमति देता है।
ध्यान दें, निश्चित रूप से, एक धागा पैदा करना एक साइड-इफ़ेक्ट है और इस प्रकार हमारी विस्तारित भाषा अब केवल कुल नहीं है, यह अब कार्यात्मक भी नहीं है।
सिद्धांत रूप में, सब कुछ एक मल्टीथ्रेडेड प्रोग्राम करता है जो एकल-थ्रेडेड प्रोग्राम के साथ-साथ धीमी गति से किया जा सकता है।
व्यवहार में, गति अंतर इतना बड़ा हो सकता है कि कोई भी ऐसा तरीका नहीं है जो कार्य के लिए एकल-थ्रेडेड प्रोग्राम का उपयोग कर सकता है। जैसे अगर आपके पास हर रात एक बैच डेटा प्रोसेसिंग का काम चल रहा है, और एक ही धागे पर खत्म होने में 24 घंटे से अधिक समय लगता है, तो आपके पास इसे मल्टीथ्रेडेड बनाने के अलावा और कोई विकल्प नहीं है। (व्यवहार में, थ्रेशोल्ड शायद कम भी है: अक्सर ऐसे अपडेट कार्य सुबह जल्दी खत्म होने चाहिए, इससे पहले कि उपयोगकर्ता फिर से सिस्टम का उपयोग करना शुरू कर दें। इसके अलावा, अन्य कार्य उन पर निर्भर हो सकते हैं, जिन्हें उसी रात के दौरान भी समाप्त करना होगा। उपलब्ध रनटाइम कुछ घंटों / मिनटों जितना कम हो सकता है।)
कई थ्रेड्स पर कंप्यूटिंग कार्य करना वितरित प्रसंस्करण का एक रूप है; आप कई थ्रेड पर काम वितरित कर रहे हैं। वितरित प्रसंस्करण का एक और उदाहरण (कई थ्रेड्स के बजाय कई कंप्यूटरों का उपयोग करना) SETI स्क्रीनसेवर है: एक प्रोसेसर पर इतना माप डेटा क्रंच करने से एक भयानक समय लगेगा और शोधकर्ता सेवानिवृत्ति से पहले परिणाम देखना पसंद करेंगे;; हालांकि, वे इतने लंबे समय के लिए सुपर कंप्यूटर किराए पर लेने के लिए बजट नहीं है, इसलिए वे इसे सस्ता बनाने के लिए लाखों घरेलू पीसी पर नौकरी वितरित करते हैं।
यद्यपि थ्रेड्स अनुक्रमिक गणना से एक छोटा कदम प्रतीत होता है, वास्तव में, वे एक विशाल कदम का प्रतिनिधित्व करते हैं। वे अनुक्रमिक संगणना के सबसे आवश्यक और आकर्षक गुणों को त्याग देते हैं: समझ, विश्वसनीयता, और नियतात्मकता। गणना के एक मॉडल के रूप में थ्रेड्स, बेतहाशा nondeterministic हैं, और प्रोग्रामर का काम उस nondeterminism को आगे बढ़ाने में से एक बन जाता है।
- थ्रेड्स की समस्या (www.eecs.berkeley.edu/Pubs/TechRpts/2006/EECS-2006-1.pdf)।
जबकि कुछ प्रदर्शन लाभ हैं जो थ्रेड्स का उपयोग करके हो सकते हैं जिसमें आप कई कोर में काम वितरित कर सकते हैं, वे अक्सर एक महान मूल्य पर आते हैं।
धागे का उपयोग करने के लिए डाउनसाइड्स में से एक का उल्लेख यहां अभी तक नहीं किया गया है जो कि संसाधन थ्रेडलाइज़ेशन का नुकसान है जो आपको सिंगल थ्रेडेड प्रोसेस स्पेस के साथ मिलता है। उदाहरण के लिए, मान लें कि आप सेगफॉल्ट के मामले में भाग रहे हैं। यह कुछ मामलों में, बहु-प्रक्रिया के आवेदन में इससे उबरने के लिए संभव है कि आप बस गलती करने वाले बच्चे को मरने दें और एक नया जवाब दें। यह अपाचे के पूर्ववर्ती बैकएंड में मामला है। जब एक httpd उदाहरण बेली जाता है, तो इससे भी बुरा मामला यह है कि विशेष HTTP अनुरोध को उस प्रक्रिया के लिए छोड़ दिया जा सकता है, लेकिन Apache एक नए बच्चे को जन्म देती है और अक्सर अनुरोध यदि बस नाराज और सेवित हो। अंतिम परिणाम यह है कि अपाचे एक पूरे के रूप में दोषपूर्ण धागे के साथ नहीं लिया जाता है।
इस परिदृश्य में एक और विचार स्मृति लीक है। कुछ ऐसे मामले हैं जहां आप किसी धागे को दुर्घटनाग्रस्त होने से बचा सकते हैं (UNIX पर, कुछ विशिष्ट संकेतों से पुनर्प्राप्त करना - यहां तक कि segfault / fpviolation संभव है), लेकिन उस मामले में भी, आपने उस धागे से आवंटित सभी मेमोरी को लीक कर दिया होगा। (मॉलोक, नया, आदि)। इसलिए जब आप प्रक्रिया पर रहते हैं, तो यह प्रत्येक दोष / रिकवरी के साथ समय के साथ अधिक से अधिक मेमोरी लीक करता है। फिर से, इसे कम करने के कुछ तरीके हैं जैसे कि अपाचे मेमोरी पूल का उपयोग। लेकिन यह अभी भी स्मृति के खिलाफ गार्ड नहीं है जो कि थर्ड पार्टी के कामों द्वारा आवंटित किया गया हो सकता है जो कि थ्रेड का उपयोग कर रहा है।
और, जैसा कि कुछ लोगों ने बताया है, सिंक्रनाइज़ेशन प्राइमेटिविटी को समझना शायद वास्तव में सही पाने के लिए सबसे मुश्किल चीज है। यह समस्या अपने आप में - बस आपके सभी कोड के लिए सामान्य तर्क सही होना - एक बहुत बड़ा सिरदर्द हो सकता है। रहस्यमय गतिरोधों को सबसे अजीब समय पर होने का खतरा होता है, और कभी-कभी ऐसा भी नहीं होता है जब तक कि आपका कार्यक्रम उत्पादन में नहीं चल रहा हो, जो सभी डिबगिंग को और अधिक कठिन बना देता है। इस तथ्य को जोड़ें कि सिंक्रोनाइज़ेशन प्राइमेटिव्स अक्सर प्लेटफ़ॉर्म (विंडोज बनाम POSIX) के साथ व्यापक रूप से भिन्न होते हैं, और डिबगिंग अक्सर अधिक कठिन हो सकती है, साथ ही साथ दौड़ की स्थिति के लिए किसी भी समय संभावना हो सकती है (स्टार्टअप / आरंभीकरण, रनटाइम, और शटडाउन)। थ्रेड्स के साथ प्रोग्रामिंग वास्तव में शुरुआती लोगों के लिए थोड़ी दया है। और विशेषज्ञों के लिए भी, अभी भी थोड़ी दया है क्योंकि केवल थ्रेडिंग का ज्ञान सामान्य रूप से जटिलता को कम नहीं करता है। थ्रेडेड कोड की प्रत्येक पंक्ति कभी-कभी कार्यक्रम की समग्र जटिलता को विस्तार देती प्रतीत होती है और साथ ही किसी भी समय एक छिपे हुए गतिरोध या अजीब दौड़ की स्थिति की संभावना को बढ़ा देती है। इन चीजों को दूर करने के लिए परीक्षण मामलों को लिखना बहुत मुश्किल हो सकता है।
यही कारण है कि Apache और PostgreSQL जैसी कुछ परियोजनाएं अधिकांश भाग प्रक्रिया-आधारित हैं। PostgreSQL प्रत्येक बैकएंड थ्रेड को एक अलग प्रक्रिया में चलाता है। बेशक यह अभी भी सिंक्रनाइज़ेशन और दौड़ की स्थिति की समस्या को कम नहीं करता है, लेकिन यह काफी सुरक्षा में जोड़ता है और कुछ तरीकों से चीजों को सरल करता है।
निष्पादन की एकल थ्रेड चलाने वाली कई प्रक्रियाएँ एक ही प्रक्रिया में चलने वाले कई थ्रेड्स से बेहतर हो सकती हैं। और AMQP (RabbitMQ, Qpid, इत्यादि) और ZeroMQ जैसे नए पीयर-टू-पीयर कोड के बहुत से आगमन के साथ, विभिन्न प्रक्रियाओं और यहां तक कि मशीनों और नेटवर्क पर थ्रेड्स को विभाजित करना बहुत आसान है, चीजों को बहुत सरल बना रहा है। लेकिन फिर भी, यह चांदी की गोली नहीं है। इससे निपटने के लिए अभी भी जटिलता है। आप अपने कुछ चर को नेटवर्क में प्रोसेस स्पेस से स्थानांतरित करते हैं।
लब्बोलुआब यह है कि धागे के क्षेत्र में प्रवेश करने का निर्णय एक प्रकाश नहीं है। एक बार जब आप उस क्षेत्र में जाते हैं, तो लगभग तुरंत ही सब कुछ अधिक जटिल हो जाता है और समस्याओं की पूरी नई नस्लें आपके जीवन में प्रवेश कर जाती हैं। यह मज़ेदार और ठंडा हो सकता है, लेकिन यह परमाणु शक्ति की तरह है - जब चीजें गलत हो जाती हैं, तो वे बुरी तरह से और तेजी से जा सकते हैं। मुझे याद है कि कई साल पहले वे बहुत ही महत्वपूर्ण प्रशिक्षण ले रहे थे और उन्होंने लॉस एलामोस के कुछ वैज्ञानिकों की तस्वीरें दिखाईं, जो WWII में प्रयोगशालाओं में प्लूटोनियम के साथ खेलते थे। कई लोगों ने एक्सपोज़र की घटना के खिलाफ बहुत कम या कोई सावधानी नहीं बरती, और पलक झपकते ही - एक ही उज्ज्वल, दर्द रहित फ्लैश में, यह सब उनके लिए खत्म हो जाएगा। कुछ दिनों बाद वे मर गए। रिचर्ड फेनमैन ने बाद में इसे " ड्रैगन की पूंछ को गुदगुदी " के रूप में संदर्भित किया। "यह उस तरह का है जो थ्रेड्स के साथ खेल रहा है, जैसे (कम से कम मेरे लिए वैसे भी) हो सकता है। यह पहली बार में बल्कि अहानिकर लगता है, और जब तक आपका काटता है, तब तक आपके सिर को खरोंचने से कितनी जल्दी चीजें खट्टी हो जाती हैं। लेकिन कम से कम धागे जीत गए। 'तुम्हें मारना नहीं है।
सबसे पहले, एक एकल थ्रेडेड एप्लिकेशन कभी भी मल्टी-कोर सीपीयू या हाइपर-थ्रेडिंग का लाभ नहीं उठाएगा। लेकिन सिंगल कोर पर, सिंगल थ्रेडेड सीपीयू मल्टी-थ्रेडिंग करने के भी फायदे हैं।
विकल्प पर विचार करें और क्या यह आपको खुश करता है। मान लीजिए कि आपके पास कई कार्य हैं जिन्हें एक साथ चलाने की आवश्यकता है। उदाहरण के लिए आपको दो अलग-अलग प्रणालियों के साथ संचार करते रहना होगा। मल्टी-थ्रेडिंग के बिना आप यह कैसे करते हैं? आप शायद अपना खुद का शेड्यूलर बनाएंगे और इसे उन विभिन्न कार्यों को कॉल करने देंगे जिन्हें करने की आवश्यकता है। इसका मतलब है कि आपको अपने कार्यों को भागों में विभाजित करने की आवश्यकता है। आपको शायद कुछ वास्तविक समय की बाधाओं को पूरा करने की आवश्यकता है जो आपको यह सुनिश्चित करना चाहिए कि आपके हिस्से बहुत अधिक समय नहीं लेते हैं। अन्यथा टाइमर अन्य कार्यों में समाप्त हो जाएगा। इससे किसी कार्य को विभाजित करना अधिक कठिन हो जाता है। अपने आप को प्रबंधित करने के लिए जितने अधिक कार्य करने की आवश्यकता है, उतने ही अधिक विभाजन को करने की जरूरत है और आपके शेड्यूलर को सभी बाधाओं को पूरा करने के लिए और अधिक जटिल हो जाएगा।
जब आपके पास कई सूत्र हैं तो जीवन आसान हो सकता है। एक पूर्व-खाली शेड्यूलर किसी भी समय एक थ्रेड को रोक सकता है, अपनी स्थिति रख सकता है, और दूसरे को फिर से शुरू (शुरू) कर सकता है। जब आपका धागा अपनी बारी आएगा तो यह फिर से चालू हो जाएगा। लाभ: एक अनुसूचक लिखने की जटिलता आपके लिए पहले ही हो चुकी है और आपको अपने कार्यों को विभाजित करने की आवश्यकता नहीं है। इसके अलावा, शेड्यूलर प्रक्रियाओं / थ्रेड्स को प्रबंधित करने में सक्षम है जो आप स्वयं भी नहीं जानते हैं। और यह भी, जब एक थ्रेड को कुछ भी करने की आवश्यकता नहीं है (यह किसी घटना की प्रतीक्षा कर रहा है) तो यह सीपीयू चक्र नहीं लेगा। यह पूरा करने के लिए इतना आसान नहीं है जब आप अपना डाउन-थ्रेडेड शेड्यूलर बना रहे हों। (सोने के लिए कुछ डालना इतना मुश्किल नहीं है, लेकिन यह कैसे जागता है?)
मल्टी-थ्रेडेड विकास का नकारात्मक पक्ष यह है कि आपको समसामयिक मुद्दों, लॉकिंग रणनीतियों आदि के बारे में समझने की आवश्यकता है। त्रुटि-रहित मल्टी-थ्रेडेड कोड विकसित करना काफी कठिन हो सकता है। और डिबगिंग और भी कठिन हो सकता है।
क्या ऐसा कुछ मौजूद है जो केवल कई धागों का उपयोग करके पूरा किया जा सकता है?
हाँ। आप एक ही धागे से कई सीपीयू या सीपीयू कोर पर कोड नहीं चला सकते हैं।
कई सीपीयू / कोर के बिना, थ्रेड्स अभी भी कोड को सरल बना सकते हैं जो वैचारिक रूप से समानांतर में चलता है, जैसे कि सर्वर पर क्लाइंट हैंडलिंग - लेकिन आप थ्रेड के बिना एक ही काम कर सकते हैं।
थ्रेड्स न केवल गति के बारे में हैं, बल्कि संगामिति के बारे में भी हैं।
यदि आपके पास @Peter जैसा कोई बैच अनुप्रयोग नहीं है, लेकिन इसके बजाय एक GUI टूलकिट WPF की तरह कैसे आप केवल एक धागे के साथ उपयोगकर्ताओं और व्यापार तर्क के साथ बातचीत कर सकते हैं?
यह भी मान लीजिए कि आप एक वेब सर्वर बना रहे हैं। आप केवल एक थ्रेड के साथ एक से अधिक उपयोगकर्ता कैसे सेवा करेंगे (कोई अन्य प्रक्रिया नहीं)?
ऐसे कई परिदृश्य हैं जहां केवल एक धागा सरल पर्याप्त नहीं है। यही कारण है कि हाल ही में उन्नति जैसे कि इंटेल एमआईसी प्रोसेसर 50+ से अधिक कोर और सैकड़ों धागे के साथ हो रहा है।
हां, समानांतर और समवर्ती प्रोग्रामिंग कठिन है। लेकिन जरूरी है।
मल्टी-थ्रेडिंग जीयूआई इंटरफ़ेस को लंबे प्रसंस्करण कार्यों के दौरान अभी भी उत्तरदायी बना सकता है। मल्टी-थ्रेडिंग के बिना, एक लंबी प्रक्रिया के चलने के दौरान उपयोगकर्ता लॉक किए गए फ़ॉर्म को देखता रहता था।
मल्टी-थ्रेडेड कोड प्रोग्राम लॉजिक को एक्सेस कर सकता है और बासी डेटा को उन तरीकों से एक्सेस कर सकता है जो सिंगल थ्रेड नहीं कर सकते हैं।
थ्रेड्स एक अस्पष्ट बग को ले सकते हैं कुछ से औसत प्रोग्रामर को डिबग करने और इसे दायरे में ले जाने की उम्मीद की जा सकती है जहां कहानियों को उसी बग को पकड़ने के लिए आवश्यक भाग्य के बारे में बताया जाता है, जब एक सतर्क प्रोग्रामर को सिर्फ देखने के लिए हुआ था। सही वक्त।
ब्लॉकिंग आईओ के साथ काम करने वाले ऐप्स जिन्हें अन्य इनपुट्स (जीयूआई या अन्य कनेक्शनों) के प्रति उत्तरदायी रहना पड़ता है, उन्हें बिना पढ़े नहीं बनाया जा सकता है
IO lib में जाँच के तरीकों को जोड़ने के अलावा यह देखने के लिए कि बिना अवरोध के कितना पढ़ा जा सकता है, इससे मदद मिल सकती है लेकिन कई पुस्तकालय इसके लिए कोई गारंटी नहीं देते हैं
बहुत सारे अच्छे उत्तर, लेकिन मुझे यकीन नहीं है कि कोई भी वाक्यांश इसे काफी पसंद करेगा - शायद यह इसे देखने का एक अलग तरीका प्रदान करता है:
थ्रेड्स केवल ऑब्जेक्ट्स या एक्टर्स की तरह एक प्रोग्रामिंग सरलीकरण हैं या लूप्स के लिए (हां, कुछ भी जो आप लूप्स के साथ कार्यान्वित करते हैं यदि आप / गोटो के साथ लागू कर सकते हैं)।
धागे के बिना आप बस एक राज्य इंजन को लागू करते हैं। मुझे कई बार ऐसा करना पड़ा है (पहली बार मैंने ऐसा किया था, जिसके बारे में मैंने कभी नहीं सुना - बस एक "राज्य" चर द्वारा नियंत्रित एक बड़ा स्विच स्टेटमेंट बनाया गया)। राज्य मशीनें अभी भी काफी सामान्य हैं, लेकिन कष्टप्रद हो सकती हैं। धागे के साथ बॉयलरप्लेट का एक बड़ा हिस्सा चला जाता है।
उन्होंने यह भी एक भाषा के लिए यह आसान बनाने के लिए होता है कि यह मल्टी-सीपीयू के अनुकूल विखंडू में रनटाइम निष्पादन को तोड़ता है (इसलिए अभिनेताओं, मुझे विश्वास है)।
जावा सिस्टम पर "ग्रीन" थ्रेड्स प्रदान करता है जहां ओएस कोई थ्रेडिंग समर्थन प्रदान नहीं करता है। इस मामले में यह देखना आसान है कि वे स्पष्ट रूप से एक प्रोग्रामिंग अमूर्त से ज्यादा कुछ नहीं हैं।
ओएस टाइम स्लाइसिंग कॉन्सेप्ट का उपयोग करता है जहां प्रत्येक थ्रेड को चलाने का समय मिल जाता है और फिर प्रीमेप्ट हो जाता है। दृष्टिकोण ऐसा है जो थ्रेडिंग को बदल सकता है क्योंकि यह अब खड़ा है, लेकिन हर एप्लिकेशन में अपने स्वयं के शेड्यूल लिखने से ओवरकिल हो जाएगा। इसके अलावा, आपको I / O उपकरणों और इतने पर काम करना होगा। और हार्डवेयर पक्ष से कुछ समर्थन की आवश्यकता होगी, ताकि आप अपने शेड्यूलर को चलाने के लिए बाधित कर सकें। मूल रूप से आप हर बार एक नया ओएस लिख रहे होंगे।
सामान्य थ्रेडिंग में उन मामलों में प्रदर्शन में सुधार हो सकता है जहां धागे I / O की प्रतीक्षा करते हैं, या सो रहे हैं। यह आपको ऐसे इंटरफेस बनाने की अनुमति देता है जो उत्तरदायी हैं, और जब आप लंबे कार्य करते हैं, तो प्रक्रियाओं को रोकने की अनुमति देते हैं। और यह भी, थ्रेडिंग मल्टीकोर सीपीयू पर चीजों को बेहतर बनाता है।
सबसे पहले, थ्रेड्स एक ही समय में दो या अधिक चीजें कर सकते हैं (यदि आपके पास एक से अधिक कोर हैं)। जब आप कई प्रक्रियाओं के साथ भी ऐसा कर सकते हैं, तो कुछ कार्य बस कई प्रक्रियाओं को बहुत अच्छी तरह से वितरित नहीं करते हैं।
इसके अलावा, कुछ कार्यों में रिक्त स्थान होते हैं जिनसे आप आसानी से बच नहीं सकते हैं। उदाहरण के लिए, डिस्क पर फ़ाइल से डेटा पढ़ना मुश्किल है और साथ ही आपकी प्रक्रिया उसी समय कुछ और करना है। यदि आपके कार्य के लिए डिस्क से बहुत सारे रीडिंग डेटा की आवश्यकता होती है, तो आपकी प्रक्रिया डिस्क के इंतजार में बहुत समय बिताएगी, चाहे आप कुछ भी करें।
दूसरा, थ्रेड्स आपको अपने कोड की बड़ी मात्रा का अनुकूलन करने से बचने की अनुमति दे सकते हैं जो प्रदर्शन-महत्वपूर्ण नहीं हैं। यदि आपके पास केवल एक ही धागा है, तो कोड का प्रत्येक टुकड़ा प्रदर्शन महत्वपूर्ण है। यदि यह ब्लॉक हो जाता है, तो आप डूब जाते हैं - कोई भी कार्य जो उस प्रक्रिया द्वारा नहीं किया जाएगा, आगे की प्रगति कर सकता है। थ्रेड्स के साथ, एक ब्लॉक केवल उस थ्रेड को प्रभावित करेगा और अन्य थ्रेड्स के साथ आ सकते हैं और उन कार्यों पर काम कर सकते हैं जो उस प्रक्रिया द्वारा किए जाने की आवश्यकता है।
एक अच्छा उदाहरण बार-बार निष्पादित त्रुटि कोड है। मान लें कि कोई कार्य बहुत ही त्रुटिपूर्ण त्रुटि का सामना करता है और उस त्रुटि को स्मृति में पेज करने के लिए कोड को संभालना पड़ता है। यदि डिस्क व्यस्त है, और प्रक्रिया में केवल एक ही धागा है, तो कोई भी आगे की प्रगति तब तक नहीं की जा सकती है जब तक कि कोड को उस त्रुटि को संभालने के लिए मेमोरी में लोड नहीं किया जा सकता है। यह फूटी प्रतिक्रिया का कारण बन सकता है।
एक अन्य उदाहरण यह है कि यदि आप बहुत कम ही डेटाबेस लुकअप कर सकते हैं। यदि आप डेटाबेस के जवाब देने के लिए प्रतीक्षा करते हैं, तो आपका कोड बहुत देरी करेगा। लेकिन आप इस सभी कोड को अतुल्यकालिक बनाने की परेशानी में नहीं जाना चाहते हैं क्योंकि यह इतना दुर्लभ है कि आपको इन लुकअप को करने की आवश्यकता है। इस काम को करने के लिए एक सूत्र के साथ, आप दोनों दुनियाओं में सर्वश्रेष्ठ हैं। इस काम को करने के लिए एक धागा इसे गैर-प्रदर्शन महत्वपूर्ण बनाता है जैसा कि यह होना चाहिए।