मॉड्यूल पाठ (1/5)
गोरोइन्स: हल्की समानता
A goroutine गो द्वारा प्रबंधित समवर्ती निष्पादन की एक इकाई है
रनटाइम. आप किसी फ़ंक्शन के सामने go कीवर्ड के साथ एक लॉन्च करते हैं
कॉल करें:
go greet("Anna") // chiamata a funzione esistente
go func() { // funzione anonima
fmt.Println("hi")
}()go स्टेटमेंट तुरंत लौटता है: गोरोइन शुरू होता है
समानांतर और कॉल करने वाला चलता रहता है।
वे "हल्के" क्यों हैं
- प्रारंभिक स्टैक ~2केबी (जरूरत पड़ने पर सैकड़ों एमबी तक गतिशील रूप से बढ़ता है)।
- रनटाइम (
GOMAXPROCS) द्वारा छोटी संख्या में OS थ्रेड्स पर मल्टीप्लेक्स। - हजारों/लाखों गोरौटाइन नियमित हैं; ओएस थ्रेड्स के साथ वे असंभव होंगे।
संकल्पनात्मक रूप से यह "समवर्ती आग लगाओ और भूल जाओ" है, लेकिन सभी के साथ
समन्वय के लिए मुहावरेदार उपकरण (चैनल, sync.WaitGroup,
context).
मुख्य इंतजार नहीं करता
func main() {
go func() { fmt.Println("ciao dalla goroutine") }()
// main esce subito: niente garanzia che la goroutine completi
}जब main वापस आता है, तो प्रक्रिया समाप्त हो जाती है: गोरोइन नहीं मिलता है
"अपना काम ख़त्म करने" के लिए, उन्हें बस एक साथ मार दिया जाता है
प्रक्रिया. स्पष्ट समन्वयन आवश्यक है.
तुल्यकालन: एक पूर्वावलोकन
तीन उपकरण आप अगले पाठों में देखेंगे:
// 1) Channel: la goroutine "segnala" via canale
done := make(chan struct{})
go func() {
work()
done <- struct{}{}
}()
<-done // attendi
// 2) sync.WaitGroup: N goroutine
var wg sync.WaitGroup
wg.Add(1)
go func() { defer wg.Done(); work() }()
wg.Wait()
// 3) context: cancellazione/timeout propagati"क्लासिक" क्लोजर-इन-लूप बग
गो 1.21 तक यह एक बार-बार होने वाली गच्चा थी:
for i := 0; i < 3; i++ {
go func() { fmt.Println(i) }() // stampa "3 3 3" su versioni vecchie
}गो 1.22 से for वेरिएबल प्रत्येक पर नए सिरे से बनाया गया है
पुनरावृत्ति, इसलिए बग डिफ़ॉल्ट रूप से ठीक हो गया है। पुराने कोडबेस में आप ऐसा करेंगे
अभी भी फिक्स पैटर्न देखें:
for i := 0; i < 3; i++ {
i := i // shadow esplicito
go func() { fmt.Println(i) }()
}
// oppure passa come argomento:
for i := 0; i < 3; i++ {
go func(n int) { fmt.Println(n) }(i)
}गोरौटाइन != ओएस थ्रेड
| पहलू | गोरौटाइन | ओएस थ्रेड |
|---|---|---|
| प्रारंभिक ढेर | ~2 केबी | 1-8 एमबी (शुरुआत में आवंटित) |
| सृजन | नैनोसेकंड | माइक्रोसेकंड |
| शेड्यूलिंग | रनटाइम पर जाएं (सहयोगी) | कर्नेल (प्रीमेप्टिव) |
| व्यावहारिक गणना | 100K+ | कुछ हजार |
एक एकल OS थ्रेड कई गोरआउट्स को होस्ट कर सकता है। रनटाइम चलता रहता है जरूरत पड़ने पर थ्रेड्स में गोरआउट्स।
इसे अजमाएं
ग्रीट फ़ंक्शन को गोरोइन के रूप में लॉन्च करें और समय के साथ 100ms प्रतीक्षा करें। मुख्य से बाहर निकलने से पहले सो जाएं।
संकेत दिखाएँ
फ़ंक्शन कॉल के सामने `go` गोरोइन लॉन्च करता है।
3 प्रयासों के बाद समाधान उपलब्ध है
एक अनाम फ़ंक्शन को गोरोइन के रूप में लॉन्च करें जो 'हाय' प्रिंट करता है।
संकेत दिखाएँ
एक अनाम फ़ंक्शन को अनुगामी `()`: `go func(){...}()` के साथ कॉल किया जाता है।
3 प्रयासों के बाद समाधान उपलब्ध है
यदि गोरौटाइन पूरा होने से पहले `मुख्य` बाहर निकल जाए तो क्या होगा?
func main() {
go work()
// main ritorna immediatamente
}संक्षिप्त
go f()ने f() को समवर्ती रूप से लॉन्च किया; यह तुरंत वापस आ जाता है.- गोरौटाइन = ~2 केबी प्रारंभिक, कुछ ओएस थ्रेड्स पर मल्टीप्लेक्स।
mainप्रतीक्षा नहीं करता: आपको सिंक्रनाइज़ेशन (चैनल/प्रतीक्षा समूह/संदर्भ) की आवश्यकता है।time.Sleepकेवल उपदेशात्मक है, उत्पादन में समन्वय के लिए कभी नहीं।- गो 1.22 से
forवैरिएबल प्रत्येक पुनरावृत्ति पर "ताज़ा" है (अब "3 3 3" बग नहीं)।