ప్రధాన కంటెంట్‌కు వెళ్లండి
మాడ్యూల్ 7 · 5లో పాఠం 1కోర్సులో 31/50~12 min
మాడ్యూల్ పాఠాలు (1/5)

గోరౌటీన్స్: తేలికైన సమాంతరత

ఒక గోరౌటిన్ అనేది గో ద్వారా నిర్వహించబడే ఏకకాలిక అమలు యొక్క యూనిట్ అమలు సమయం. మీరు ఫంక్షన్ ముందు go కీవర్డ్‌తో ఒకదాన్ని ప్రారంభించండి కాల్:

Go
go greet("Anna")         // chiamata a funzione esistente
go func() {              // funzione anonima
    fmt.Println("hi")
}()

go స్టేట్‌మెంట్ వెంటనే తిరిగి వస్తుంది: గోరౌటిన్ ప్రారంభమవుతుంది సమాంతరంగా మరియు కాలర్ కొనసాగుతుంది.

అవి ఎందుకు "తేలికైనవి"

  • ప్రారంభ స్టాక్ ~2KB (అవసరమైతే వందల MB వరకు డైనమిక్‌గా పెరుగుతుంది).
  • రన్‌టైమ్ (GOMAXPROCS) ద్వారా తక్కువ సంఖ్యలో OS థ్రెడ్‌లపై మల్టీప్లెక్స్ చేయబడింది.
  • వేల/మిలియన్ల గోరౌటీన్‌లు నిత్యకృత్యం; OS థ్రెడ్‌లతో అవి అసాధ్యం.

సంభావితంగా ఇది "ఏకకాలిక అగ్ని-మరియు-మర్చి", కానీ అన్నిటితో సమన్వయం చేయడానికి ఇడియోమాటిక్ సాధనాలు (ఛానెల్‌లు, sync.WaitGroup, context).

ప్రధాన వేచి లేదు

Go
func main() {
    go func() { fmt.Println("ciao dalla goroutine") }()
    // main esce subito: niente garanzia che la goroutine completi
}

main తిరిగి వచ్చినప్పుడు, ప్రాసెస్ ముగుస్తుంది: గోరౌటీన్‌లు పొందలేరు "వారి పనిని పూర్తి చేయడానికి", వారు కేవలం వారితో కలిసి చంపబడతారు ప్రక్రియ. స్పష్టమైన సమకాలీకరణ అవసరం.

సమకాలీకరణ: ఒక ప్రివ్యూ

మీరు తదుపరి పాఠాలలో చూసే మూడు సాధనాలు:

Go
// 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 వరకు ఇది తరచుగా గోచా:

Go
for i := 0; i < 3; i++ {
    go func() { fmt.Println(i) }()  // stampa "3 3 3" su versioni vecchie
}

Go 1.22 నుండి for వేరియబుల్ ప్రతిదానిపై తాజాగా సృష్టించబడింది పునరావృతం, కాబట్టి బగ్ డిఫాల్ట్‌గా పరిష్కరించబడుతుంది. పాత కోడ్‌బేస్‌లలో మీరు చేస్తారు ఇప్పటికీ పరిష్కార నమూనాను చూడండి:

Go
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)
}

గోరూటిన్ != OS థ్రెడ్

కోణంగోరూటిన్OS థ్రెడ్
ప్రారంభ స్టాక్~2 KB1–8 MB (ప్రారంభంలో కేటాయించబడింది)
సృష్టినానోసెకన్లుమైక్రోసెకన్లు
షెడ్యూలింగ్గో రన్‌టైమ్ (సహకార)కెర్నల్ (ముందస్తు)
ప్రాక్టికల్ కౌంట్100K+కొన్ని వేల

ఒకే OS థ్రెడ్ అనేక గోరౌటిన్‌లను హోస్ట్ చేయగలదు. రన్‌టైమ్ కదులుతుంది అవసరమైనప్పుడు థ్రెడ్‌ల అంతటా గోరూటీన్‌లు.

దీనిని ప్రయత్నించండి

వ్యాయామం#go.m7.l1.e1
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

గ్రీట్ ఫంక్షన్‌ను గోరూటీన్‌గా ప్రారంభించి, సమయంతో పాటు 100మి.లు వేచి ఉండండి. మెయిన్ నుండి నిష్క్రమించే ముందు నిద్రపోండి.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

ఫంక్షన్ కాల్ ముందు `గో` గోరౌటిన్‌ని లాంచ్ చేస్తుంది.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

వ్యాయామం#go.m7.l1.e2
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

'హాయ్' అని ప్రింట్ చేసే గోరౌటిన్‌గా అనామక ఫంక్షన్‌ను ప్రారంభించండి.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

అనామక ఫంక్షన్ `()`: `go func(){...}()` ట్రైలింగ్‌తో పిలువబడుతుంది.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

Quiz#go.m7.l1.e3
సిద్ధంగా ఉంది

గోరౌటిన్ పూర్తయ్యేలోపు `మెయిన్` నిష్క్రమిస్తే ఏమి జరుగుతుంది?

Go
func main() {
  go work()
  // main ritorna immediatamente
}
సమాధాన ఎంపికలు

రీక్యాప్

  • go f() f()ని ఏకకాలంలో లాంచ్ చేస్తుంది; అది వెంటనే తిరిగి వస్తుంది.
  • గోరౌటిన్ = ~2 KB ప్రారంభ, కొన్ని OS థ్రెడ్‌లలో మల్టీప్లెక్స్ చేయబడింది.
  • main వేచి ఉండదు: మీకు సమకాలీకరణ అవసరం (ఛానల్/వెయిట్‌గ్రూప్/సందర్భం).
  • time.Sleep అనేది ఉపదేశానికి సంబంధించినది, ఉత్పత్తిలో సమకాలీకరణ కోసం ఎప్పుడూ ఉండదు.
  • గో 1.22 నుండి for వేరియబుల్ ప్రతి పునరావృతంలో "ఫ్రెష్"గా ఉంటుంది (ఇక "3 3 3" బగ్ లేదు).