मल्टीथ्रेडिंग और मल्टीप्रोसेसिंग समवर्ती और समांतरता प्राप्त करने के दो सबसे आम तरीके हैं, हालांकि, कई डेवलपर्स उनके बीच के अंतर को नहीं समझते हैं और प्रभावी ढंग से चुनने में असफल होते हैं कि कब उपयोग करना है।
इस लेख में, हम मल्टीथ्रेडिंग और मल्टीप्रोसेसिंग के बीच के अंतरों पर चर्चा करेंगे और यह तय करेंगे कि पायथन में क्या उपयोग करना है और इसे कैसे लागू करना है।
एक धागा निष्पादन का एक स्वतंत्र प्रवाह है। इसे अनिवार्य रूप से एक प्रक्रिया के हल्के व्यक्तिगत घटक के रूप में देखा जा सकता है, जो समानांतर रूप से चल सकता है। थ्रेडिंग आमतौर पर ऑपरेटिंग सिस्टम द्वारा प्रदान की जाने वाली एक विशेषता है। एक प्रक्रिया में कई थ्रेड हो सकते हैं, जो समान मेमोरी स्पेस साझा करते हैं, जिसका अर्थ है कि वे कोड को निष्पादित करने के लिए साझा करते हैं और प्रोग्राम में घोषित चर एक दूसरे के साथ साझा करते हैं।
इसे बेहतर ढंग से समझने के लिए, आइए अभी आपके लैपटॉप पर चल रहे प्रोग्रामों के एक उदाहरण पर विचार करें। आप शायद इस लेख को अपने ब्राउज़र में कई टैब खुले हुए पढ़ रहे हैं। इस बीच, संगीत सुनने के लिए आपके पास Spotify डेस्कटॉप ऐप खुला है। अब, ब्राउज़र और Spotify डेस्कटॉप ऐप दो अलग-अलग प्रक्रियाओं की तरह हैं जो समानांतरता प्राप्त करने के लिए कई प्रक्रियाओं या थ्रेड्स को नियोजित कर सकते हैं। तो, आपके ब्राउज़र में अलग-अलग टैब अलग-अलग थ्रेड में चलाए जा सकते हैं। इसी तरह, Spotify एक थ्रेड का उपयोग करके संगीत चला सकता है और इंटरनेट से अपना पसंदीदा गाना डाउनलोड करने के लिए दूसरे का उपयोग कर सकता है, और उपयोगकर्ता इंटरफ़ेस प्रदर्शित करने के लिए तीसरे का उपयोग कर सकता है। और इसे मल्टीथ्रेडिंग कहा जाता है।
मल्टीथ्रेडिंग, जैसा कि नाम से पता चलता है, एक कार्य या एक ऑपरेशन है जो एक ही समय में कई थ्रेड्स को निष्पादित कर सकता है। यह एक लोकप्रिय तकनीक है जो एक ही समय में कई कार्यों को त्वरित उत्तराधिकार में सुव्यवस्थित करती है, और मुख्य धागे के साथ कई थ्रेड्स के बीच संसाधनों के त्वरित और आसान साझाकरण की सुविधा प्रदान करती है।
निम्नलिखित छवि पायथन में मल्टीथ्रेडिंग की व्याख्या करती है:
पायथन एक रैखिक भाषा है, लेकिन हम पायथन में मल्टीथ्रेडिंग की अवधारणा को समझने और लागू करने के लिए थ्रेडिंग पायथन मॉड्यूल का उपयोग कर सकते हैं। थ्रेडिंग मॉड्यूल आसानी से कई थ्रेड उत्पन्न करने के लिए एक सहज एपीआई प्रदान करता है जिसका उपयोग तब किया जा सकता है जब अधिक प्रसंस्करण शक्ति की आवश्यकता होती है।
इसका उपयोग नीचे दिखाए अनुसार किया जा सकता है:
import threading from queue import Queue import time def testThread(num): print num if __name__ == '__main__': for i in range(5): t = threading.Thread(target=testThread, arg=(i,)) t.start()
उपरोक्त कोड स्निपेट में, target
को कॉल करने योग्य ऑब्जेक्ट के रूप में उपयोग किया जाता है, args
को पैरामीटर पास करने और थ्रेड start
करने के लिए तर्क देता है।
अब, यहाँ कुछ दिलचस्प आता है - ताला।
प्रोग्रामिंग में अक्सर ऐसे मामले होते हैं जहां आप चाहते हैं कि आपके धागे थ्रेड के लिए सामान्य चर को संशोधित या उपयोग करने में सक्षम हों। हालांकि, ऐसा करने के लिए, आपको पाइथन में लॉक या ग्लोबल इंटरप्रेटर लॉक (जीआईएल) के नाम से जाना जाने वाला कुछ उपयोग करना होगा।
अजगर से
सीपीथॉन में, वैश्विक दुभाषिया लॉक , या जीआईएल , एक म्यूटेक्स है जो पायथन ऑब्जेक्ट्स तक पहुंच की रक्षा करता है, कई थ्रेड्स को एक साथ पायथन बाइटकोड को निष्पादित करने से रोकता है। यह लॉक मुख्य रूप से आवश्यक है क्योंकि CPython का मेमोरी प्रबंधन थ्रेड-सुरक्षित नहीं है।
दुभाषिया स्तर पर, पायथन मूल रूप से निर्देशों को क्रमबद्ध करता है। किसी भी थ्रेड को किसी भी फ़ंक्शन को चलाने के लिए, उसे पहले ग्लोबल लॉक प्राप्त करना होगा। चूंकि एक समय में केवल एक ही धागा उस लॉक को प्राप्त कर सकता है, दुभाषिया को अंत में निर्देशों को क्रमिक रूप से निष्पादित करना होगा। यह आर्किटेक्चर मेमोरी प्रबंधन को थ्रेड-सुरक्षित बनाता है, लेकिन यह कई CPU कोर का उपयोग बिल्कुल नहीं कर सकता है।
सीधे शब्दों में कहें, जब भी कोई फ़ंक्शन किसी चर का उपयोग या संशोधन करना चाहता है, तो वह उस चर को लॉक कर देता है जैसे कि यदि कोई अन्य फ़ंक्शन उस विशिष्ट चर का उपयोग या संशोधित करना चाहता है, तो उसे उस चर के अनलॉक होने तक प्रतीक्षा करनी होगी।
दो कार्यों पर विचार करें, जिनमें से प्रत्येक एक चर को एक-एक करके पुनरावृत्त करता है। आप यह सुनिश्चित करने के लिए लॉक का उपयोग कर सकते हैं कि एक फ़ंक्शन चर को पढ़ सकता है, गणना चला सकता है, और दूसरे फ़ंक्शन से पहले इसे वापस लिख सकता है, ताकि हम डेटा भ्रष्टाचार से बच सकें।
पायथन में थ्रेडिंग I/O संचालन या नेटवर्क-बाध्य कार्य के लिए अधिक सहायक है जैसे कि स्क्रिप्ट चलाना, उदाहरण के लिए, वेब स्क्रैपिंग के मामले में उन कार्यों के बजाय जो CPU गहन हो सकते हैं। एक अन्य उदाहरण Tensorflow है, जो समानांतर में डेटा को बदलने के लिए थ्रेड पूल का उपयोग करता है।
इन अनुप्रयोगों के अलावा, ग्राफिकल यूजर इंटरफेस (जीयूआई) अनुप्रयोगों को उत्तरदायी और इंटरैक्टिव बनाने के लिए हर समय मल्टीथ्रेडिंग का उपयोग करते हैं। एक सामान्य उदाहरण टेक्स्ट एडिटिंग प्रोग्राम हो सकता है जहां जैसे ही उपयोगकर्ता टेक्स्ट इनपुट करता है, यह स्क्रीन पर प्रदर्शित होता है। यहां एक थ्रेड उपयोगकर्ता इनपुट का ख्याल रखता है जबकि दूसरा थ्रेड इसे प्रदर्शित करने के लिए कार्य को संभालता है। हम अधिक कार्यात्मकताओं जैसे वर्तनी जांच, स्वत: पूर्णता आदि के लिए और धागे जोड़ सकते हैं।
अब, थ्रेड्स पर विस्तार से चर्चा करने के बाद, प्रक्रियाओं पर चलते हैं।
एक प्रक्रिया केवल कंप्यूटर प्रोग्राम को निष्पादित करने का एक उदाहरण है। प्रत्येक प्रक्रिया का अपना मेमोरी स्पेस होता है जिसका उपयोग चलाए जा रहे निर्देशों को संग्रहीत करने के लिए किया जाता है, और कोई भी डेटा जिसे कोड के निष्पादन के लिए एक्सेस या स्टोर करने की आवश्यकता होती है। इस वजह से, थ्रेड की तुलना में स्पॉनिंग एक प्रक्रिया अधिक समय लेने वाली और धीमी होती है।
जैसा कि हमने पहले चर्चा की, जब हम अपने डेस्कटॉप पर कई एप्लिकेशन चला रहे होते हैं, तो प्रत्येक एप्लिकेशन एक प्रक्रिया होती है और जब इन प्रक्रियाओं को एक ही समय में निष्पादित किया जाता है, तो इसे मल्टीप्रोसेसिंग कहा जाता है।
मल्टीप्रोसेसिंग एक प्रोसेसर की एक साथ कई असंबंधित कार्यों को निष्पादित करने की क्षमता है। यह आपको ऐसे प्रोग्राम बनाने की अनुमति देता है जो ग्लोबल इंटरप्रेटर लॉक (जीआईएल) को दरकिनार करते हुए समवर्ती रूप से चल सकते हैं और कार्यों के कुशल निष्पादन के लिए पूरे सीपीयू कोर का उपयोग कर सकते हैं।
हालांकि मल्टीप्रोसेसिंग की अवधारणा मूल रूप से मल्टीथ्रेडिंग से अलग है, फिर भी पायथन में उनका सिंटैक्स या उपयोग काफी समान है। थ्रेडिंग मॉड्यूल के समान, हमारे पास पायथन में एक मल्टीप्रोसेसिंग मॉड्यूल है जो विभिन्न प्रक्रियाओं को उत्पन्न करने में मदद करता है, जहां प्रत्येक प्रक्रिया का अपना पायथन दुभाषिया और एक GIL होता है।
चूंकि प्रक्रियाएं समान मेमोरी को साझा नहीं करती हैं, इसलिए वे एक ही मेमोरी को समवर्ती रूप से संशोधित नहीं कर सकती हैं, जिससे हमें गतिरोध या डेटा भ्रष्टाचार की संभावना के जोखिम से बचाया जा सकता है।
इसका उपयोग नीचे दिखाए अनुसार किया जा सकता है:
import multiprocessing def spawn(num): print(num) if __name__ == '__main__': for i in range(5): p = multiprocessing.Process(target=spawn, args=(i,)) p.start() p.join() # this line allows you to wait for processes
जैसा कि हमने पहले भी चर्चा की थी, यदि कार्य CPU व्यापक हैं और कोई I/O संचालन या उपयोगकर्ता इंटरैक्शन नहीं है, तो Mutliprocessing एक बुद्धिमान विकल्प है।
मल्टीप्रोसेसिंग और मल्टीथ्रेडिंग के अंतर, गुण और कमियों को संक्षेप में प्रस्तुत करने के लिए यहां कुछ बिंदु दिए गए हैं:
इस चर्चा से हम निम्नलिखित निष्कर्ष निकाल सकते हैं:
अब जब आप समझ गए हैं कि पायथन मल्टीप्रोसेसिंग और मल्टीथ्रेडिंग कैसे काम करते हैं और वे कैसे तुलना करते हैं, तो आप प्रभावी ढंग से कोड लिख सकते हैं और विभिन्न परिस्थितियों में दो दृष्टिकोणों को लागू कर सकते हैं।
मुझे आशा है कि आपको यह लेख मददगार लगा होगा। पढ़ते रहिये!