Go में समवर्तीता और मल्टीथ्रेडिंग: A से Z तक

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

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

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

Go में समवर्तीता और मल्टीथ्रेडिंग: A से Z तक

\n\n

Go (Golang) को आधुनिक कंप्यूटिंग लोड को ध्यान में रखकर डिज़ाइन किया गया था। मल्टी-कोर प्रोसेसर और क्लाउड सेवाओं के युग में, समवर्तीता के साथ कुशलतापूर्वक काम करना बैकएंड डेवलपर के लिए एक अनिवार्य कौशल बन गया है। इस लेख में, हम देखेंगे कि Go समानांतर कोड निष्पादन की समस्याओं को कैसे हल करता है, गोरूटीन OS थ्रेड्स से कैसे भिन्न हैं, और चैनल और म्यूटेक्स का सही उपयोग कैसे करें।

\n\n

1. गोरूटीन: हल्के थ्रेड्स

\n\n

गोरूटीन (goroutine) एक फ़ंक्शन या मेथड है जो अन्य गोरूटीन के साथ समवर्ती रूप से निष्पादित होता है। ऑपरेटिंग सिस्टम थ्रेड्स के विपरीत, गोरूटीन में न्यूनतम ओवरहेड होता है: उनका स्टैक 2-4 KB से शुरू होता है और गतिशील रूप से बढ़ सकता है। गोरूटीन शुरू करना अविश्वसनीय रूप से आसान है - बस फ़ंक्शन कॉल से पहले कीवर्ड go जोड़ें।

\n\n
package main\n\nimport (\n    "fmt"\n    "time"\n)\n\nfunc say(text string) {\n    for i := 0; i < 3; i++ {\n        fmt.Println(text)\n        time.Sleep(100 * time.Millisecond)\n    }\n}\n\nfunc main() {\n    go say("Hello from goroutine")\n    say("Hello from main")\n    // गोरूटीन को पूरा होने का समय दें\n    time.Sleep(500 * time.Millisecond)\n}
\n\n

ध्यान दें: प्रोग्राम main() फ़ंक्शन के निष्पादन के तुरंत बाद समाप्त हो जाता है, शुरू की गई गोरूटीन के पूरा होने की प्रतीक्षा किए बिना। सिंक्रोनाइज़ेशन के लिए हम time.Sleep का उपयोग करते हैं (वास्तविक प्रोजेक्ट्स में - sync.WaitGroup या चैनल)।

\n\n

2. चैनल: सुरक्षित डेटा ट्रांसफर

\n\n

चैनल (channels) टाइप किए गए "पाइप" हैं जिनके माध्यम से गोरूटीन डेटा का आदान-प्रदान करते हैं। वे दो मुख्य कार्यों को हल करते हैं: निष्पादन का सिंक्रोनाइज़ेशन और मानों का स्थानांतरण। चैनल बफ़र किए गए और बिना बफ़र वाले हो सकते हैं।

\n\n

बिना बफ़र वाला चैनल

\n

भेजने का ऑपरेशन गोरूटीन को तब तक ब्लॉक करता है जब तक कोई दूसरी गोरूटीन रीड नहीं कर लेती। यह "ऑन-द-फ्लाई" सिंक्रोनाइज़ेशन सुनिश्चित करता है।

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    ch := make(chan string)\n\n    go func() {\n        ch <- "गोरूटीन से नमस्ते!"\n    }()\n\n    msg := <-ch\n    fmt.Println(msg)\n}
\n\n

बफ़र किया गया चैनल

\n

बफ़र वाला चैनल बिना तुरंत पढ़े कई मान भेजने की अनुमति देता है, जब तक बफ़र भर न जाए।

\n\n
package main\n\nimport "fmt"\n\nfunc main() {\n    ch := make(chan int, 2)\n    ch <- 10\n    ch <- 20\n    // ch <- 30 // deadlock! बफ़र भर गया\n\n    fmt.Println(<-ch) // 10\n    fmt.Println(<-ch) // 20\n}
\n\n

Range और close

\n

चैनल को बंद करना प्राप्तकर्ताओं को संकेत देता है कि और डेटा नहीं आएगा। for range लूप चैनल बंद होने पर स्वचालित रूप से समाप्त हो जाता है।

\n\n
package main\n\nimport "fmt"\n\nfunc producer(ch chan int) {\n    for i := 1; i <= 5; i++ {\n        ch <- i\n    }\n    close(ch)\n}\n\nfunc main() {\n    ch := make(chan int)\n    go producer(ch)\n\n    for val := range ch {\n        fmt.Println("प्राप्त:", val)\n    }\n}
\n\n

3. सिंक्रोनाइज़ेशन और म्यूटेक्स

\n\n

चैनल की शक्ति के बावजूद, कभी-कभी साझा डेटा तक सीधी पहुँच की आवश्यकता होती है। sync पैकेज क्रिटिकल सेक्शन की सुरक्षा के लिए म्यूटेक्स (sync.Mutex) और रीडर-म्यूटेक्स (sync.RWMutex) प्रदान करता है।

\n\n
package main\n\nimport (\n    "fmt"\n    "sync"\n)\n\nvar counter = 0\nvar mu sync.Mutex\n\nfunc increment(wg *sync.WaitGroup) {\n    defer wg.Done()\n    mu.Lock()\n    counter++\n    mu.Unlock()\n}\n\nfunc main() {\n    var wg sync.WaitGroup\n    for i := 0; i < 1000; i++ {\n        wg.Add(1)\n        go increment(&wg)\n    }\n    wg.Wait()\n    fmt.Println("अंतिम काउंटर:", counter)\n}
\n\n

यहाँ sync.WaitGroup सभी गोरूटीन के पूरा होने की प्रतीक्षा करता है, और म्यूटेक्स डेटा रेस (data race) को रोकता है। म्यूटेक्स के बिना, परिणाम अप्रत्याशित होगा।

\n\n

4. समवर्तीता पैटर्न

ब्लॉग

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