पाठ 14 / 26
Goroutines and WaitGroups
Thousands of lightweight tasks.
go f() and waiting for completion
A goroutine is a lightweight concurrent function started with go f(); the runtime multiplexes many goroutines onto a few OS threads, so thousands are cheap. The program does not wait for goroutines automatically: use a sync.WaitGroup (Go 1.25 added wg.Go(func(){...}), which handles Add and Done for you) or channels to wait. Give each goroutine its own data or synchronise access; since Go 1.22 each loop iteration has its own copy of the loop variable, fixing a classic bug.
Goroutines and channels
Go makes concurrency cheap with goroutines, coordinates it with channels and context, and checks it with the race detector.
Five concurrent fetches, run
I ran this with Go 1.27.1 (go run . in a module named demo, standard library only). Five simulated 100 ms calls run concurrently, each writing its own slot of the results slice, and finish in well under the 500 ms a sequential loop would need.
package main
import (
"fmt"
"sync"
"time"
)
func fetch(id int) string {
time.Sleep(100 * time.Millisecond) // pretend network call
return fmt.Sprintf("result-%d", id)
}
func main() {
start := time.Now()
results := make([]string, 5)
var wg sync.WaitGroup
for i := range 5 {
wg.Go(func() { // Go 1.25+: WaitGroup.Go adds, runs and marks done
results[i] = fetch(i) // each goroutine writes its own index
})
}
wg.Wait()
fmt.Println(results)
fmt.Println("took under 300ms:", time.Since(start) < 300*time.Millisecond)
}
Output:
[result-0 result-1 result-2 result-3 result-4] took under 300ms: true
Bound concurrency
For many tasks, limit parallelism (a worker pool or a semaphore channel) so you do not overwhelm downstream services.
त्वरित जाँच: Does main wait for goroutines it started before exiting?
- Only if they print output
- Yes, always
- Only for the first goroutine
- No, you must wait explicitly, for example with a WaitGroup
Answer
No, you must wait explicitly, for example with a WaitGroup — Coordinate completion explicitly.