Help us improve
Share bugs, ideas, or general feedback.
From golang
Go 并发编程规范:goroutine 生命周期管理、errgroup 并发编排、context 超时取消传播、sync.Pool 对象复用、go.uber.org/atomic 原子操作、channel 模式、Go 1.23 iter 迭代器。适用于并发设计、竞态排查、性能调优场景。
npx claudepluginhub lazygophers/ccplugin --plugin golangHow this skill is triggered — by the user, by Claude, or both
Slash command
/golang:concurrencysonnetThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
- **dev** - 开发专家(主要使用者)
Guides writing, reviewing, and auditing concurrent Go code using goroutines, channels, select, locks, sync primitives, errgroup, singleflight, and worker pools. Detects leaks, races, and ownership issues.
Guides Go concurrency: goroutine lifetimes with WaitGroups, channels for communication, mutexes for shared state, preventing leaks and data races.
Master Go concurrency with goroutines, channels, sync primitives, and context. Use for building concurrent Go applications, worker pools, or debugging race conditions.
Share bugs, ideas, or general feedback.
| 场景 | Skill | 说明 |
|---|---|---|
| 核心规范 | Skills(golang:core) | 核心规范:强制约定 |
| 错误处理 | Skills(golang:error) | errgroup 错误处理模式 |
| 测试 | Skills(golang:testing) | 并发测试和 race 检测 |
| 工具 | Skills(golang:tooling) | go test -race、pprof |
import "go.uber.org/atomic"
counter := atomic.NewInt64(0)
counter.Inc()
counter.Add(10)
val := counter.Load()
flag := atomic.NewBool(false)
flag.Toggle()
flag.Store(true)
name := atomic.NewString("")
name.Store("hello")
var bufferPool = sync.Pool{
New: func() any {
return new(bytes.Buffer)
},
}
func processData(data []byte) string {
buf := bufferPool.Get().(*bytes.Buffer)
defer bufferPool.Put(buf)
buf.Reset()
buf.Write(data)
return buf.String()
}
import "golang.org/x/sync/errgroup"
eg, ctx := errgroup.WithContext(ctx)
for _, item := range items {
item := item // Go 1.22 之前需要捕获
eg.Go(func() error {
return process(ctx, item)
})
}
err = eg.Wait()
if err != nil {
log.Errorf("err:%v", err)
return err
}
eg, ctx := errgroup.WithContext(ctx)
eg.SetLimit(10) // 最多 10 个并发 goroutine
for _, url := range urls {
url := url
eg.Go(func() error {
return fetch(ctx, url)
})
}
// 带超时的 context
ctx, cancel := context.WithTimeout(ctx, 5*time.Second)
defer cancel()
// 带取消的 context
ctx, cancel := context.WithCancel(ctx)
defer cancel()
// context 传播到所有下游调用
func processItem(ctx context.Context, item *Item) error {
select {
case <-ctx.Done():
return ctx.Err()
default:
// 正常处理
}
return nil
}
import (
"iter"
"maps"
"slices"
)
// range-over-func 迭代 map
for k, v := range maps.All(m) {
fmt.Println(k, v)
}
// range-over-func 迭代 slice
for i, v := range slices.All(s) {
fmt.Println(i, v)
}
// 自定义迭代器
func FilterIter[T any](seq iter.Seq[T], fn func(T) bool) iter.Seq[T] {
return func(yield func(T) bool) {
for v := range seq {
if fn(v) {
if !yield(v) {
return
}
}
}
}
}
result := make([]string, 0, len(items))
for _, item := range items {
result = append(result, item.String())
}
import "github.com/lazygophers/log"
buf := log.GetBuffer()
defer log.PutBuffer(buf)
func TestConcurrentAccess(t *testing.T) {
counter := NewCounter()
var wg sync.WaitGroup
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
counter.Increment()
}()
}
wg.Wait()
if counter.Value() != 100 {
t.Errorf("counter = %d, want 100", counter.Value())
}
}
| AI 可能的理性化解释 | 实际应该检查的内容 | 严重程度 |
|---|---|---|
| "sync/atomic 是标准库" | 是否使用 go.uber.org/atomic? | 高 |
| "mutex 更简单" | 简单场景是否用 atomic 替代 mutex? | 中 |
| "goroutine 很轻量无所谓" | 是否用 errgroup 管理,无泄漏风险? | 高 |
| "context 到处传太麻烦" | goroutine 是否通过 context 控制? | 高 |
| "不需要并发限制" | errgroup 是否设置了 SetLimit? | 中 |
| "iter 太新了不稳定" | 适合场景是否使用了 range-over-func? | 低 |