Go में समवर्तीता: गोरूटीन, चैनल और async/await (तुलना)

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Go ने समवर्तीता में सबको पीछे क्यों छोड़ा?

\n\n

एक शेफ की कल्पना करें जो एक साथ दस व्यंजन बना रहा है। वह पागलों की तरह एक चूल्हे से दूसरे चूल्हे तक नहीं भागता - वह बस कार्यों के बीच कुशलता से स्विच करता है: जब मांस पक रहा होता है, तो सलाद काटता है; जब पानी उबल रहा होता है, तो प्लेट सजाता है। प्रोग्रामिंग की दुनिया में इसे समवर्तीता कहा जाता है - प्रत्येक कार्य के पूरा होने की प्रतीक्षा किए बिना कई कार्यों को प्रबंधित करने की क्षमता।

\n\n

Go भाषा (Golang) का जन्म समवर्तीता की समस्याओं को हल करने के लिए ही हुआ था। Google के इसके निर्माता C++ और Java में मल्टीथ्रेडिंग की जटिलताओं से थक गए थे। उन्होंने गोरूटीन बनाए - हल्के-फुल्के थ्रेड जो कोड की एक पंक्ति से शुरू होते हैं। इस लेख में, हम समझेंगे कि Go में समवर्तीता कैसे काम करती है, इसकी तुलना OS थ्रेड्स और Python के async/await प्रतिमान से करेंगे, और सबसे महत्वपूर्ण बात, वास्तविक कोड उदाहरण दिखाएंगे जिन्हें आप आज ही लागू कर सकते हैं।

\n\n

गोरूटीन बनाम OS थ्रेड्स: हल्की घुड़सवार सेना की लड़ाई

\n\n

जब कोई डेवलपर 'मल्टीथ्रेडिंग' सुनता है, तो वह आमतौर पर ऑपरेटिंग सिस्टम के थ्रेड्स के बारे में सोचता है। लेकिन Go में सब कुछ अलग है। आइए मुख्य अंतरों को समझें।

\n\n

OS थ्रेड क्या है?

\n

थ्रेड एक भारी वस्तु है जिसे OS कर्नेल द्वारा प्रबंधित किया जाता है। प्रत्येक थ्रेड का अपना स्टैक (आमतौर पर 1-8 MB) होता है, जिसे बनाने और स्विच करने के लिए सिस्टम कॉल की आवश्यकता होती है। 10,000 थ्रेड बनाने का मतलब है मेमोरी और CPU को मार डालना। Go में एक अलग दर्शन निहित है।

\n\n

गोरूटीन - Go का हल्का थ्रेड

\n

गोरूटीन एक फंक्शन है जो समवर्ती रूप से निष्पादित होता है। इसे कीवर्ड go से शुरू किया जाता है। मुख्य विशेषताएं:

\n
    \n
  • स्टैक का आकार: 2-4 KB से शुरू होता है और गतिशील रूप से बढ़ता/घटता है।
  • \n
  • निर्माण: हजारों गोरूटीन मिलीसेकंड में बनाए जाते हैं।
  • \n
  • शेड्यूलर: Go runtime स्वचालित रूप से गोरूटीन को OS थ्रेड्स पर वितरित करता है (आमतौर पर उनकी संख्या CPU कोर की संख्या के बराबर होती है)।
  • \n
  • सिंटैक्स: बस फंक्शन कॉल से पहले go जोड़ें।
  • \n
\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n)\n\nfunc sayHello(name string) {\n    for i := 0; i < 3; i++ {\n        fmt.Println("नमस्ते,", name)\n        time.Sleep(100 * time.Millisecond)\n    }\n}\n\nfunc main() {\n    // दो गोरूटीन शुरू करें\n    go sayHello("Go")\n    go sayHello("Goroutine")\n\n    // गोरूटीन को निष्पादित होने का समय दें\n    time.Sleep(1 * time.Second)\n    fmt.Println("मुख्य फंक्शन समाप्त")\n}
\n\n

परिणाम: दो गोरूटीन के संदेश आपस में मिल जाएंगे। Go स्वचालित रूप से उनके बीच स्विच करता है, एक दूसरे को ब्लॉक किए बिना। इस कोड को चलाने का प्रयास करें - आप देखेंगे कि 'नमस्ते, Go' और 'नमस्ते, Goroutine' बारी-बारी से प्रिंट होते हैं।

\n\n

चैनल: सिंक्रोनाइज़ेशन का मुख्य उपकरण

\n\n

गोरूटीन बहुत अच्छे हैं, लेकिन वे आपस में कैसे संवाद करें? Go में डिफ़ॉल्ट रूप से साझा मेमोरी नहीं है। इसके बजाय, सिद्धांत का उपयोग किया जाता है: 'मेमोरी साझा करके संवाद न करें; संवाद करके मेमोरी साझा करें'। इसके लिए चैनल का उपयोग किया जाता है।

\n\n

चैनल एक टाइप किया गया 'पाइपलाइन' है जिसके माध्यम से गोरूटीन डेटा भेजते और प्राप्त करते हैं। यह सुरक्षित, सरल और सुरुचिपूर्ण है।

\n\n

उदाहरण: संख्याओं का समानांतर प्रसंस्करण

\n
package main\n\nimport "fmt"\n\nfunc squareWorker(numbers <-chan int, results chan<- int) {\n    for n := range numbers {\n        results <- n * n\n    }\n    close(results)\n}\n\nfunc main() {\n    numbers := make(chan int, 5)\n    results := make(chan int, 5)\n\n    // वर्कर शुरू करें\n    go squareWorker(numbers, results)\n\n    // डेटा भेजें\n    numbers <- 2\n    numbers <- 4\n    numbers <- 6\n    close(numbers)\n\n    // परिणाम पढ़ें\n    for res := range results {\n        fmt.Println("वर्ग:", res)\n    }\n}
\n\n

इस उदाहरण में, हम बफ़र किए गए चैनल का उपयोग करते हैं (दूसरा तर्क बफ़र का आकार है)। गोरूटीन-वर्कर numbers चैनल से पढ़ता है, वर्ग करता है

ब्लॉग

पुस्तक अनुशंसाएँ