முக்கிய உள்ளடக்கத்திற்குச் செல்லவும்
eLearner.app
தொகுதி 7 · பாடம் 1 இன் 5பாடத்திட்டத்தில் 31/50~12 min
தொகுதி பாடங்கள் (1/5)

Goroutines: இலகுரக பேரலலிசம்

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