← ClaudeAtlas

go-concurrencylisted

Always use this skill when working with goroutines, channels, context, sync primitives, or concurrent Go code. Triggers include: "goroutine leak", "channel deadlock", "context cancellation", "how do I use WaitGroup", "fan-out fan-in", "worker pool", "data race", "select statement", "buffered channel", "sync.Mutex", "sync.Once", "context.WithTimeout", "goroutine exits", "channel close", "race condition", "concurrent map write". Read this skill before advising on any Go concurrency question.
AllThingsSmitty/agent-skills · ★ 1 · Code & Development · score 74
Install: claude install-skill AllThingsSmitty/agent-skills
## Goroutines Goroutines are cheap (a few KB of stack) but not free. Every goroutine must have a clear exit condition — otherwise it leaks. A goroutine leak happens when a goroutine blocks forever on a channel send, channel receive, or lock with no one to unblock it. ```go // Bad: no exit condition — leaks if done is never closed go func() { for item := range items { process(item) } }() // Good: exits on context cancellation go func() { for { select { case <-ctx.Done(): return case item, ok := <-items: if !ok { return } process(item) } } }() ``` ## Channels Unbuffered channels provide a synchronous rendezvous — sender and receiver must both be ready. Buffered channels decouple them up to the buffer size. ```go unbuffered := make(chan int) // blocks until receiver is ready buffered := make(chan int, 10) // blocks only when full ``` Use directional channel types in function signatures to make intent explicit: ```go func produce(out chan<- int) { out <- 42 } func consume(in <-chan int) { v := <-in; _ = v } ``` Only the sender should close a channel. Closing from the receiver side or closing twice panics. ```go // Range exits automatically when the channel is closed for item := range ch { process(item) } ``` ## select `select` lets a goroutine wait on multiple channel operations simultaneously. **Timeout with context:** ```go select {