नोड के पास एक पूरी तरह से अलग प्रतिमान है और एक बार इसे सही ढंग से कैप्चर करने के बाद, समस्याओं को हल करने के इस अलग तरीके को देखना आसान है। आपको नोड एप्लिकेशन (1) में कई थ्रेड्स की आवश्यकता नहीं है क्योंकि आपके पास एक ही काम करने का एक अलग तरीका है। आप कई प्रक्रियाएँ बनाते हैं; लेकिन यह तुलना में बहुत अलग है, उदाहरण के लिए Apache Web Server का Prefork mpm कैसे करता है।
अभी के लिए, आइए सोचते हैं कि हमारे पास बस एक सीपीयू कोर है और हम कुछ काम करने के लिए एक एप्लिकेशन (नोड के तरीके से) विकसित करेंगे। हमारा काम अपनी सामग्री को बाइट-बाइट पर चलाने वाली एक बड़ी फ़ाइल को संसाधित करना है। हमारे सॉफ़्टवेयर के लिए सबसे अच्छा तरीका है कि आप फ़ाइल की शुरुआत से ही काम शुरू कर दें, इसके लिए बाइट-बाइट का पालन करें।
- अरे, हसन, मुझे लगता है कि आप मेरे दादा के समय से एक नौसिखिया या बहुत पुराने स्कूल हैं !!! आप कुछ धागे क्यों नहीं बनाते हैं और इसे बहुत तेज़ बनाते हैं?
- ओह, हमारे पास केवल एक सीपीयू कोर है।
-- तो क्या? कुछ थ्रेड मैन बनाएं, इसे तेज करें!
- यह उस तरह काम नहीं करता है। अगर मैं धागे बनाऊं तो मैं इसे धीमा कर दूंगा। क्योंकि मैं थ्रेड्स के बीच स्विच करने के लिए सिस्टम में बहुत अधिक ओवरहेड जोड़ रहा हूं, उन्हें थोड़ी देर देने की कोशिश कर रहा हूं, और मेरी प्रक्रिया के अंदर, इन थ्रेड्स के बीच संवाद करने की कोशिश कर रहा हूं। इन सभी तथ्यों के अलावा, मुझे यह भी सोचना होगा कि मैं किसी एक काम को कई टुकड़ों में कैसे विभाजित करूँगा जो समानांतर में किया जा सकता है।
- ठीक है ठीक है, मैं देख रहा हूं कि आप गरीब हैं। चलो मेरे कंप्यूटर का उपयोग करें, इसमें 32 कोर हैं!
- वाह, आप मेरे प्यारे दोस्त हैं, बहुत-बहुत धन्यवाद। मैं इसकी सराहना करता हूं!
फिर हम काम पर वापस लौटते हैं। अब हमारे पास अपने अमीर दोस्त की बदौलत 32 सीपीयू कोर हैं। हमें नियमों का पालन करना होगा बस बदल गया है। अब हम अपने द्वारा दिए गए इस धन का उपयोग करना चाहते हैं।
एकाधिक कोर का उपयोग करने के लिए, हमें अपने काम को टुकड़ों में विभाजित करने का एक तरीका खोजने की आवश्यकता है जिसे हम समानांतर में संभाल सकते हैं। यदि यह नोड नहीं था, तो हम इसके लिए थ्रेड्स का उपयोग करेंगे; 32 धागे, प्रत्येक सीपीयू कोर के लिए एक। हालाँकि, चूंकि हमारे पास नोड है, हम 32 नोड प्रक्रियाएँ बनाएंगे।
थ्रेड्स नोड प्रक्रियाओं का एक अच्छा विकल्प हो सकता है, शायद एक बेहतर तरीका भी; लेकिन केवल एक विशिष्ट प्रकार की नौकरी में, जहां काम पहले से ही परिभाषित है और हमें इस पर पूरा नियंत्रण है कि इसे कैसे संभालना है। इसके अलावा, हर दूसरी तरह की समस्या के लिए जहां नौकरी एक तरह से बाहर से आती है पर हमारा नियंत्रण नहीं होता है और हम जल्द से जल्द जवाब देना चाहते हैं, नोड का तरीका बहुत बेहतर है।
- अरे, हसन, क्या आप अभी भी सिंगल-थ्रेडेड काम कर रहे हैं? तुममें क्या खराबी है, यार? मैंने आपको वही प्रदान किया है जो आप चाहते थे। आपके पास अब कोई बहाना नहीं है। धागे बनाएँ, इसे तेज चलाएं।
- मैंने काम को टुकड़ों में विभाजित किया है और हर प्रक्रिया समानांतर में इनमें से किसी एक टुकड़े पर काम करेगी।
- आप थ्रेड्स क्यों नहीं बनाते हैं?
- क्षमा करें, मुझे नहीं लगता कि यह प्रयोग करने योग्य है। आप चाहें तो अपना कंप्यूटर ले सकते हैं
- नहीं ठीक है, मैं शांत हूँ, मुझे समझ में नहीं आता कि आप थ्रेड्स का उपयोग क्यों नहीं करते हैं?
- कंप्यूटर के लिए धन्यवाद। :) मैंने पहले से ही काम को टुकड़ों में विभाजित किया है और मैं इन टुकड़ों पर समानांतर में काम करने के लिए प्रक्रियाएं बनाता हूं। सभी सीपीयू कोर का पूरा उपयोग किया जाएगा। मैं प्रक्रियाओं के बजाय थ्रेड्स के साथ ऐसा कर सकता था; लेकिन नोड के पास यह तरीका है और मेरे बॉस पार्थ ठक्कर चाहते हैं कि मैं नोड का इस्तेमाल करूं।
- ठीक है, मुझे बताएं कि क्या आपको दूसरे कंप्यूटर की आवश्यकता है। : p
यदि मैं 32 के बजाय 33 प्रक्रियाएं बनाता हूं, तो ऑपरेटिंग सिस्टम का शेड्यूलर एक थ्रेड को रोक देगा, दूसरे को शुरू करें, इसे कुछ चक्रों के बाद रोकें, दूसरे को फिर से शुरू करें ... यह अनावश्यक ओवरहेड है। मैं यह नहीं चाहता। वास्तव में, 32 कोर वाली प्रणाली पर, मैं वास्तव में 32 प्रक्रियाएँ बनाना नहीं चाहूंगा, 31 हो सकते हैं अच्छे । क्योंकि यह सिर्फ मेरा आवेदन नहीं है जो इस प्रणाली पर काम करेगा। अन्य चीजों के लिए थोड़ा कमरा छोड़ना अच्छा हो सकता है, खासकर अगर हमारे पास 32 कमरे हैं।
मेरा मानना है कि हम सीपीयू-गहन कार्यों के लिए प्रोसेसर का पूरी तरह से उपयोग करने के बारे में अब उसी पृष्ठ पर हैं ।
- हम्म, हसन, मुझे आपसे थोड़ा मजाक करने का अफसोस है। मेरा मानना है कि मैं अब आपको बेहतर समझ रहा हूं। लेकिन अभी भी कुछ है जिसके लिए मुझे एक स्पष्टीकरण की आवश्यकता है: सैकड़ों धागे चलाने के बारे में क्या चर्चा है? मैं हर जगह पढ़ता हूं कि थ्रेडिंग प्रक्रियाओं की तुलना में थ्रेड बनाने और गूंगा करने के लिए बहुत तेज़ हैं? आप थ्रेड्स के बजाय प्रक्रियाओं को कांटा करते हैं और आपको लगता है कि यह सबसे अधिक है जो आपको नोड के साथ मिलेगा। तब क्या नोड इस तरह के काम के लिए उपयुक्त नहीं है?
- कोई चिंता नहीं, मैं शांत हूं। हर कोई इन चीजों को कहता है इसलिए मुझे लगता है कि मैं उन्हें सुनने के आदी हूं।
-- इसलिए? इसके लिए नोड अच्छा नहीं है?
- नोड इसके लिए पूरी तरह से अच्छा है, हालांकि थ्रेड्स भी अच्छे हो सकते हैं। धागा / प्रक्रिया निर्माण उपरि के लिए के रूप में; उन चीजों पर जो आप बहुत दोहराते हैं, हर मिलीसेकंड मायने रखता है। हालाँकि, मैं केवल 32 प्रक्रियाएँ बनाता हूँ और इसमें थोड़ा समय लगेगा। यह केवल एक बार ही होगा। इससे कोई फर्क नहीं पड़ेगा।
- जब मैं हजारों धागे बनाना चाहता हूं, तब?
- आप कभी हजारों सूत्र नहीं बनाना चाहते। हालाँकि, एक ऐसे सिस्टम पर जो काम कर रहा है जो बाहर से आता है, जैसे HTTP अनुरोधों को संसाधित करने वाला वेब सर्वर; यदि आप प्रत्येक अनुरोध के लिए एक धागे का उपयोग कर रहे हैं, तो आप बहुत सारे धागे बना रहे होंगे, उनमें से कई।
- नोड अलग है, हालांकि? सही?
-- हाँ बिल्कुल। यह वह जगह है जहाँ नोड वास्तव में चमकता है। जैसे एक प्रक्रिया की तुलना में एक धागा बहुत हल्का होता है, एक फ़ंक्शन कॉल एक धागे की तुलना में बहुत हल्का होता है। थ्रेड बनाने के बजाय नोड कॉल फ़ंक्शन करता है। वेब सर्वर के उदाहरण में, प्रत्येक आने वाला अनुरोध फ़ंक्शन कॉल का कारण बनता है।
-- हां दिलचस्प; लेकिन आप एक ही समय में एक फ़ंक्शन चला सकते हैं यदि आप कई थ्रेड का उपयोग नहीं कर रहे हैं। जब एक ही समय में वेब सर्वर पर बहुत सारे अनुरोध आते हैं तो यह कैसे काम कर सकता है?
- आप पूरी तरह से सही हैं कि फ़ंक्शन कैसे चलते हैं, एक बार में, दो समानांतर में कभी नहीं। मेरा मतलब है कि एक ही प्रक्रिया में, एक समय में कोड का केवल एक क्षेत्र चल रहा है। ओएस शेड्यूलर नहीं आता है और इस फ़ंक्शन को रोक देता है और किसी अन्य पर स्विच करता है, जब तक कि यह हमारी प्रक्रिया में किसी अन्य थ्रेड को नहीं, किसी अन्य प्रक्रिया को समय देने की प्रक्रिया को रोक देता है। (2)
- फिर एक समय में एक प्रक्रिया 2 अनुरोधों को कैसे संभाल सकती है?
- एक प्रक्रिया एक समय में हजारों अनुरोधों को संभाल सकती है जब तक कि हमारे सिस्टम में पर्याप्त संसाधन (रैम, नेटवर्क, आदि) हैं। उन कार्यों को कैसे चलाया जाता है प्रमुख कुंजी है।
- हम्म, क्या मुझे अब उत्साहित होना चाहिए?
- शायद :) नोड एक कतार पर एक लूप चलाता है। इस कतार में हमारे काम हैं, यानी, आने वाले अनुरोधों को संसाधित करने के लिए कॉल। यहां सबसे महत्वपूर्ण बिंदु वह तरीका है जिससे हम अपने कार्यों को चलाने के लिए डिज़ाइन करते हैं। अनुरोध को संसाधित करने और कॉल करने की प्रतीक्षा करने के बजाय जब तक हम काम खत्म नहीं कर लेते, तब तक हम स्वीकार्य कार्य करने के बाद अपने कार्य को जल्दी समाप्त कर देते हैं। जब हम एक ऐसे बिंदु पर आते हैं, जहाँ हमें किसी काम को करने के लिए दूसरे घटक की प्रतीक्षा करनी होती है और हमें उसका मूल्य वापस करना होता है, तो उसके लिए प्रतीक्षा करने के बजाय, हम बस अपने काम को बाकी काम को कतार में जोड़कर पूरा करते हैं।
- यह बहुत जटिल लगता है?
- नहीं, मैं जटिल लग सकता है; लेकिन सिस्टम ही बहुत सरल है और यह सही समझ में आता है।
अब मैं इन दोनों डेवलपर्स के बीच संवाद का हवाला देते हुए रोकना चाहता हूं और इन कार्यों को कैसे काम करता हूं इसका एक अंतिम त्वरित उदाहरण के बाद अपना जवाब समाप्त करता हूं।
इस तरह, हम वह कर रहे हैं जो ओएस शेड्यूलर सामान्य रूप से करता है। हम अपने काम को कुछ बिंदु पर रोकते हैं और अन्य फ़ंक्शन कॉल (जैसे कि एक बहु-थ्रेडेड वातावरण में अन्य थ्रेड) चलाते हैं जब तक कि हम अपनी बारी फिर से प्राप्त नहीं करते हैं। यह ओएस शेड्यूलर पर काम छोड़ने से बहुत बेहतर है जो सिस्टम पर हर थ्रेड को बस समय देने की कोशिश करता है। हम जानते हैं कि ओएस शेड्यूलर की तुलना में हम क्या बेहतर कर रहे हैं और हमें उम्मीद है कि हमें रुकना चाहिए।
नीचे एक सरल उदाहरण है जहां हम एक फ़ाइल खोलते हैं और इसे डेटा पर कुछ काम करने के लिए पढ़ते हैं।
तुल्यकालिक तरीका:
Open File
Repeat This:
Read Some
Do the work
अतुल्यकालिक तरीका:
Open File and Do this when it is ready: // Our function returns
Repeat this:
Read Some and when it is ready: // Returns again
Do some work
जैसा कि आप देखते हैं, हमारा फ़ंक्शन सिस्टम को एक फ़ाइल खोलने के लिए कहता है और इसके खुलने का इंतजार नहीं करता है। यह फ़ाइल तैयार होने के बाद अगले चरण प्रदान करके खुद को पूरा करता है। जब हम लौटते हैं, तो नोड कतार में अन्य फ़ंक्शन कॉल चलाता है। सभी कार्यों पर चलने के बाद, इवेंट लूप अगले मोड़ पर जाता है ...
सारांश में, नोड के पास बहु-थ्रेडेड विकास की तुलना में पूरी तरह से अलग प्रतिमान है; लेकिन इसका मतलब यह नहीं है कि इसमें चीजों की कमी है। एक तुल्यकालिक नौकरी के लिए (जहां हम प्रसंस्करण के क्रम और तरीके को तय कर सकते हैं), यह बहु-सूत्रित समानता के रूप में भी काम करता है। एक नौकरी के लिए जो बाहर से सर्वर के लिए अनुरोध की तरह आता है, यह बस बेहतर है।
(1) जब तक आप C / C ++ जैसी अन्य भाषाओं में पुस्तकालयों का निर्माण नहीं कर रहे हैं, उस स्थिति में आप अभी भी नौकरियों को विभाजित करने के लिए सूत्र नहीं बनाते हैं। इस तरह के काम के लिए आपके पास दो धागे हैं जिनमें से एक में नोड के साथ संचार जारी रहेगा जबकि दूसरा वास्तविक कार्य करता है।
(२) वास्तव में, प्रत्येक नोड प्रक्रिया में पहले फुटनोट में उल्लिखित समान कारणों के लिए कई सूत्र हैं। हालाँकि यह कोई ऐसा तरीका नहीं है जैसे 1000 धागे समान कार्य करते हैं। वे अतिरिक्त धागे IO ईवेंट्स को स्वीकार करने और इंटर-प्रोसेस मैसेजिंग को संभालने जैसी चीजों के लिए हैं।
अद्यतन (टिप्पणियों में एक अच्छे प्रश्न के उत्तर के रूप में)
@ मर्क, रचनात्मक आलोचना के लिए धन्यवाद। नोड के प्रतिमान में, आपको कभी भी ऐसे कार्य नहीं करने चाहिए जो प्रक्रिया में बहुत समय लेते हैं जब तक कि कतार में अन्य सभी कॉल को एक के बाद एक चलाने के लिए डिज़ाइन नहीं किया गया हो। कम्प्यूटेशनल रूप से महंगे कार्यों के मामले में, यदि हम पूरी तरह से तस्वीर को देखते हैं, तो हम देखते हैं कि यह "क्या हमें धागे या प्रक्रियाओं का उपयोग नहीं करना चाहिए?" लेकिन एक सवाल "हम इन कार्यों को अच्छी तरह से संतुलित तरीके से उप-कार्यों में कैसे विभाजित कर सकते हैं कि हम उन्हें सिस्टम पर कई सीपीयू कोर के समानांतर रोजगार में चला सकते हैं?" मान लें कि हम 8 कोर के साथ एक सिस्टम पर 400 वीडियो फ़ाइलों को संसाधित करेंगे। यदि हम एक बार में एक फ़ाइल को संसाधित करना चाहते हैं, तो हमें एक ऐसी प्रणाली की आवश्यकता होती है जो एक ही फ़ाइल के विभिन्न भागों को संसाधित करेगी, जिस स्थिति में, शायद, एक बहु-थ्रेडेड एकल-प्रक्रिया प्रणाली का निर्माण करना आसान होगा और इससे भी अधिक कुशल। राज्य-साझाकरण / संचार आवश्यक होने पर हम कई प्रक्रियाओं को चलाकर और उनके बीच संदेश भेजकर इसके लिए नोड का उपयोग कर सकते हैं। जैसा कि मैंने पहले कहा, नोड के साथ एक बहु-प्रक्रिया दृष्टिकोण हैसाथ ही के रूप में कार्य के इस प्रकार में एक बहु लड़ी दृष्टिकोण; लेकिन इससे ज्यादा नहीं। फिर से, जैसा कि मैंने पहले बताया, नोड की चमक तब होती है जब हमारे पास ये कार्य कई स्रोतों से सिस्टम में इनपुट के रूप में आते हैं क्योंकि कई कनेक्शन समवर्ती रूप से नोड में थ्रेड-प्रति-कनेक्शन या प्रक्रिया-प्रति-कनेक्शन की तुलना में बहुत हल्के होते हैं प्रणाली।
setTimeout(...,0)
कॉल के लिए के रूप में ; कभी-कभी कतार में कॉल की अनुमति देने के लिए एक समय लेने वाले कार्य के दौरान एक ब्रेक देने से उनके प्रसंस्करण की हिस्सेदारी की आवश्यकता हो सकती है। विभिन्न तरीकों से विभाजित कार्य आपको इनसे बचा सकते हैं; लेकिन फिर भी, यह वास्तव में हैक नहीं है, यह सिर्फ इवेंट कतारों का काम है। इसके अलावा, process.nextTick
इस उद्देश्य के लिए उपयोग करना तब से बेहतर है जब आप उपयोग करते हैं setTimeout
, गणना और पारित किए गए समय की जांच आवश्यक होगी, जबकि process.nextTick
हम वास्तव में यही चाहते हैं: "अरे काम, कतार के अंत में वापस जाओ, आपने अपने हिस्से का उपयोग किया है! "