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

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

A goroutine is a unit of concurrent execution managed by the Go runtime. You launch one with the go keyword in front of a function call:

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

The go statement returns immediately: the goroutine starts in parallel and the caller keeps going.

Why they are "lightweight"

  • Initial stack ~2KB (grows dynamically, up to hundreds of MB if needed).
  • Multiplexed onto a small number of OS threads by the runtime (GOMAXPROCS).
  • Thousands/millions of goroutines are routine; with OS threads they would be impossible.

Conceptually it is "concurrent fire-and-forget", but with all the idiomatic tools to coordinate (channels, sync.WaitGroup, context).

main does not wait

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

When main returns, the process terminates: goroutines do not get to "finish their work", they are simply killed together with the process. Explicit synchronization is required.

Synchronization: a preview

The three tools you will see in the next lessons:

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

The "classic" closure-in-loop bug

Up to Go 1.21 this was a frequent gotcha:

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

From Go 1.22 the for variable is freshly created on each iteration, so the bug is fixed by default. In older codebases you will still see the fix pattern:

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

Goroutine != OS thread

AspectGoroutineOS thread
Initial stack~2 KB1–8 MB (allocated at start)
Creationnanosecondsmicroseconds
SchedulingGo runtime (cooperative)kernel (preemptive)
Practical count100K+a few thousand

A single OS thread can host many goroutines. The runtime moves goroutines across threads when needed.

Try it

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

Launch the greet function as a goroutine and wait 100ms with time.Sleep before exiting main.

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

`go` in front of a function call launches the goroutine.

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

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

Launch an anonymous function as a goroutine that prints 'hi'.

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

An anonymous function is called with a trailing `()`: `go func(){...}()`.

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

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

What happens if `main` exits before a goroutine completes?

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

Recap

  • go f() launches f() concurrently; it returns immediately.
  • Goroutine = ~2 KB initial, multiplexed onto a few OS threads.
  • main does not wait: you need synchronization (channel/WaitGroup/context).
  • time.Sleep is only didactic, never for sync in production.
  • From Go 1.22 the for variable is "fresh" on each iteration (no more "3 3 3" bug).