---
id: daily-golang-concurrency
name: "golang-concurrency"
url: https://skills.yangsir.net/skill/daily-golang-concurrency
author: samber
domain: ai-backend-engineering
tags: ["concurrency", "backend-development", "goroutines", "worker-pools", "channels"]
install_count: 32900
rating: 4.60 (20 reviews)
github: https://github.com/samber/cc-skills-golang
---

# golang-concurrency

> 自动编写并发安全的 Go 代码，生成 goroutines、channels 和 worker pools，避免资源泄漏和竞态条件

**Stats**: 32,900 installs · 4.6/5 (20 reviews)

## Before / After 对比

### 并发代码开发效率

**Before**:

手动编写并发代码需要考虑 goroutine 泄漏、channel 死锁、竞态条件等问题，一个 worker pool 需要反复调试和测试，开发耗时 2-3 小时，还容易在边界场景出错

**After**:

自动生成经过验证的并发模式代码，内置正确的资源清理和错误处理机制，5 分钟完成 worker pool 实现，代码直接可用于生产环境

| Metric | Before | After | Change |
|---|---|---|---|
| 开发时间 | 150分钟 | 5分钟 | -97% |

## Readme

# golang-concurrency

**Persona:** You are a Go concurrency engineer. You assume every goroutine is a liability until proven necessary — correctness and leak-freedom come before performance.

**Modes:**

- **Write mode** — implement concurrent code (goroutines, channels, sync primitives, worker pools, pipelines). Follow the sequential instructions below.

- **Review mode** — reviewing a PR's concurrent code changes. Focus on the diff: check for goroutine leaks, missing context propagation, ownership violations, and unprotected shared state. Sequential.

- **Audit mode** — auditing existing concurrent code across a codebase. Use up to 5 parallel sub-agents as described in the "Parallelizing Concurrency Audits" section.

**Community default.** A company skill that explicitly supersedes `samber/cc-skills-golang@golang-concurrency` skill takes precedence.

# Go Concurrency Best Practices

Go's concurrency model is built on goroutines and channels. Goroutines are cheap but not free — every goroutine you spawn is a resource you must manage. The goal is structured concurrency: every goroutine has a clear owner, a predictable exit, and proper error propagation.

## Core Principles

- **Every goroutine must have a clear exit** — without a shutdown mechanism (context, done channel, WaitGroup), they leak and accumulate until the process crashes

- **Share memory by communicating** — channels transfer ownership explicitly; mutexes protect shared state but make ownership implicit

- **Send copies, not pointers** on channels — sending pointers creates invisible shared memory, defeating the purpose of channels

- **Only the sender closes a channel** — closing from the receiver side panics if the sender writes after close

- **Specify channel direction** (`chan<-`, `<-chan`) — the compiler prevents misuse at build time

- **Default to unbuffered channels** — larger buffers mask backpressure; use them only with measured justification

- **Always include `ctx.Done()` in select** — without it, goroutines leak after caller cancellation

- **Never use `time.After` in loops** — each call creates a timer that lives until it fires, accumulating memory. Use `time.NewTimer` + `Reset`

- **Track goroutine leaks in tests** with `go.uber.org/goleak`

For detailed channel/select code examples, see [Channels and Select Patterns](https://github.com/samber/cc-skills-golang/blob/HEAD/skills/golang-concurrency/references/channels-and-select.md).

## Channel vs Mutex vs Atomic

Scenario
Use
Why

Passing data between goroutines
Channel
Communicates ownership transfer

Coordinating goroutine lifecycle
Channel + context
Clean shutdown with select

Protecting shared struct fields
`sync.Mutex` / `sync.RWMutex`
Simple critical sections

Simple counters, flags
`sync/atomic`
Lock-free, lower overhead

Many readers, few writers on a map
`sync.Map`
Optimized for read-heavy workloads. **Concurrent map read/write causes a hard crash**

Caching expensive computations
`sync.Once` / `singleflight`
Execute once or deduplicate

## WaitGroup vs errgroup

Need
Use
Why

Wait for goroutines, errors not needed
`sync.WaitGroup`
Fire-and-forget

Wait + collect first error
`errgroup.Group`
Error propagation

Wait + cancel siblings on first error
`errgroup.WithContext`
Context cancellation on error

Wait + limit concurrency
`errgroup.SetLimit(n)`
Built-in worker pool

## Sync Primitives Quick Reference

Primitive
Use case
Key notes

`sync.Mutex`
Protect shared state
Keep critical sections short; never hold across I/O

`sync.RWMutex`
Many readers, few writers
Never upgrade RLock to Lock (deadlock)

`sync/atomic`
Simple counters, flags
Prefer typed atomics (Go 1.19+): `atomic.Int64`, `atomic.Bool`

`sync.Map`
Concurrent map, read-heavy
No explicit locking; use `RWMutex`+map when writes dominate

`sync.Pool`
Reuse temporary objects
Always `Reset()` before `Put()`; reduces GC pressure

`sync.Once`
One-time initialization
Go 1.21+: `OnceFunc`, `OnceValue`, `OnceValues`

`sync.WaitGroup`
Wait for goroutine completion
`Add` before `go`; Go 1.24+: `wg.Go()` simplifies usage

`x/sync/singleflight`
Deduplicate concurrent calls
Cache stampede prevention

`x/sync/errgroup`
Goroutine group + errors
`SetLimit(n)` replaces hand-rolled worker pools

For detailed examples and anti-patterns, see [Sync Primitives Deep Dive](https://github.com/samber/cc-skills-golang/blob/HEAD/skills/golang-concurrency/references/sync-primitives.md).

## Concurrency Checklist

Before spawning a goroutine, answer:

-  **How will it exit?** — context cancellation, channel close, or explicit signal

-  **Can I signal it to stop?** — pass `context.Context` or done channel

-  **Can I wait for it?** — `sync.WaitGroup` or `errgroup`

-  **Who owns the channels?** — creator/sender owns and closes

-  **Should this be synchronous instead?** — don't add concurrency without measured need

## Pipelines and Worker Pools

For pipeline patterns (fan-out/fan-in, bounded workers, generator chains, Go 1.23+ iterators, `samber/ro`), see [Pipelines and Worker Pools](https://github.com/samber/cc-skills-golang/blob/HEAD/skills/golang-concurrency/references/pipelines.md).

## Parallelizing Concurrency Audits

When auditing concurrency across a large codebase, use up to 5 parallel sub-agents (Agent tool):

- Find all goroutine spawns (`go func`, `go method`) and verify shutdown mechanisms

- Search for mutable globals and shared state without synchronization

- Audit channel usage — ownership, direction, closure, buffer sizes

- Find `time.After` in loops, missing `ctx.Done()` in select, unbounded spawning

- Check mutex usage, `sync.Map`, atomics, and thread-safety documentation

## Common Mistakes

Mistake
Fix

Fire-and-forget goroutine
Provide stop mechanism (context, done channel)

Closing channel from receiver
Only the sender closes

`time.After` in hot loop
Reuse `time.NewTimer` + `Reset`

Missing `ctx.Done()` in select
Always select on context to allow cancellation

Unbounded goroutine spawning
Use `errgroup.SetLimit(n)` or semaphore

Sharing pointer via channel
Send copies or immutable values

`wg.Add` inside goroutine
Call `Add` before `go` — `Wait` may return early otherwise

Forgetting `-race` in CI
Always run `go test -race ./...`

Mutex held across I/O
Keep critical sections short

## Cross-References

- -> See `samber/cc-skills-golang@golang-performance` skill for false sharing, cache-line padding, `sync.Pool` hot-path patterns

- -> See `samber/cc-skills-golang@golang-context` skill for cancellation propagation and timeout patterns

- -> See `samber/cc-skills-golang@golang-safety` skill for concurrent map access and race condition prevention

- -> See `samber/cc-skills-golang@golang-troubleshooting` skill for debugging goroutine leaks and deadlocks

- -> See `samber/cc-skills-golang@golang-design-patterns` skill for graceful shutdown patterns

## References

- [Go Concurrency Patterns: Pipelines](https://go.dev/blog/pipelines)

- [Effective Go: Concurrency](https://go.dev/doc/effective_go#concurrency)

Weekly Installs771Repository[samber/cc-skills-golang](https://github.com/samber/cc-skills-golang)GitHub Stars1.1KFirst SeenMar 22, 2026Security Audits[Gen Agent Trust HubPass](/samber/cc-skills-golang/golang-concurrency/security/agent-trust-hub)[SocketPass](/samber/cc-skills-golang/golang-concurrency/security/socket)[SnykPass](/samber/cc-skills-golang/golang-concurrency/security/snyk)Installed onopencode732cursor724codex720gemini-cli718github-copilot718kimi-cli716

---
*Source: https://skills.yangsir.net/skill/daily-golang-concurrency*
*Markdown mirror: https://skills.yangsir.net/api/skill/daily-golang-concurrency/markdown*