Concurrency Goroutines
Goroutines, channels, and sync tools. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Search across all documentation pages
Goroutines, channels, and sync tools. Results appear in the same fence: same-line // comments when short, multiline // blocks below the sample when not.
Start a goroutine.
done := make(chan struct{})
go func() { close(done) }()
<-done // receivedUnbuffered syncs sender and receiver.
ch := make(chan int)
go func() { ch <- 7 }()
<-ch // 7Sends until buffer full.
ch := make(chan int, 1)
ch <- 1
<-ch // 1Wait on multiple channel ops.
ch := make(chan int, 1)
ch <- 2
select {
case v := <-ch:
v // 2
default:
// non-blocking path
}Wait for a set of goroutines.
var wg sync.WaitGroup
wg.Add(1)
go func() { defer wg.Done() }()
wg.Wait()
// all doneProtect shared memory.
var mu sync.Mutex
var n int
mu.Lock()
n++
mu.Unlock()
n // 1Many readers or one writer.
var mu sync.RWMutex
mu.RLock()
// read
mu.RUnlock()Signal no more sends; range exits.
ch := make(chan int, 2)
ch <- 1
ch <- 2
close(ch)
sum := 0
for v := range ch { sum += v }
sum // 3Non-blocking try.
ch := make(chan int)
select {
case <-ch:
default:
// no value ready
}Run initialization exactly once.
var once sync.Once
n := 0
once.Do(func() { n = 1 })
once.Do(func() { n = 2 })
n // 1Lock-free counters.
var n atomic.Int64
n.Add(1)
n.Load() // 1Stage channels for streaming work.
// in -> worker -> out
// each stage is a goroutine ranging inputWait + first error (golang.org/x/sync/errgroup).
// g, ctx := errgroup.WithContext(ctx)
// g.Go(func() error { ... })
// return g.Wait()Listen on ctx.Done() in workers.
// select { case <-ctx.Done(): return ctx.Err(); case ch <- v: }Nil channel cases are ignored in select.
var ch chan int // nil
select {
case <-ch:
default:
// default taken; nil ch never ready
}Stack versions: Go 1.26.x · chi/gin/echo latest (verify at build)
Reviewed by Chris St. John·Last updated Jul 18, 2026