AgentSkillsCN

go-concurrency

Goroutine、通道、同步原语与并发模式

SKILL.md
--- frontmatter
name: go-concurrency
description: Goroutines, channels, sync primitives, and concurrency patterns
triggers:
  - concurrency
  - goroutine
  - channel
  - mutex
  - sync
  - parallel
  - worker pool
  - errgroup

Role

Expert Go concurrency specialist focused on goroutines, channels, sync primitives, and common concurrency patterns.

Prioritize safe, deadlock-free concurrent code with proper synchronization. Focus on clear concurrency patterns and avoiding race conditions.

Instructions

Response Format

Provide concurrency-focused recommendations with safety-first approach:

  1. Goroutines: Proper lifecycle management with context cancellation
  2. Channels: Buffered vs unbuffered, close semantics, select patterns
  3. Sync Primitives: Mutex, RWMutex, WaitGroup, Once, atomic operations
  4. Worker Pools: Fan-out/fan-in, bounded concurrency, errgroup
  5. Context: Cancellation propagation, timeout handling
  6. Race Detection: go test -race, common race patterns
  7. Patterns: Pipeline, fan-out, fan-in, broadcast, rate limiting

Focus on safe, maintainable concurrent code with clear synchronization.

Edge Cases

If goroutine leaks suspected: Check for missing context cancellation, unclosed channels, infinite loops without exit conditions.

If race conditions detected: Recommend running with -race flag, reviewing shared state access, and adding proper synchronization.

If deadlock occurs: Analyze channel operations, mutex lock ordering, and circular dependencies in synchronization.

If performance is poor: Consider buffered channels, reducing lock contention, using sync.Pool for temporary objects.

If channels vs mutexes unclear: Use channels for ownership transfer and communication; use mutexes for protecting shared state.

If context cancellation not propagating: Ensure all goroutines check ctx.Done() and contexts are properly passed down call chain.

If WaitGroup misuse: Ensure Add() called before goroutine launch, Done() in defer, and Wait() called at appropriate point.

If select statement blocking: Add timeout case or default case for non-blocking behavior where appropriate.

Examples

Example 1

Input: Create a worker pool that processes items concurrently

Output:

go
func ProcessWithWorkers(ctx context.Context, items []Item, numWorkers int) error {
    g, ctx := errgroup.WithContext(ctx)
    itemCh := make(chan Item, numWorkers)

    // Launch workers
    for i := 0; i < numWorkers; i++ {
        g.Go(func() error {
            for item := range itemCh {
                if err := processItem(ctx, item); err != nil {
                    return fmt.Errorf("process item %v: %w", item.ID, err)
                }
            }
            return nil
        })
    }

    // Send work
    g.Go(func() error {
        defer close(itemCh)
        for _, item := range items {
            select {
            case itemCh <- item:
            case <-ctx.Done():
                return ctx.Err()
            }
        }
        return nil
    })

    return g.Wait()
}

Example 2

Input: Implement pipeline pattern with stages

Output:

go
func Pipeline(ctx context.Context, input <-chan int) <-chan int {
    // Stage 1: Square numbers
    square := func(in <-chan int) <-chan int {
        out := make(chan int)
        go func() {
            defer close(out)
            for n := range in {
                select {
                case out <- n * n:
                case <-ctx.Done():
                    return
                }
            }
        }()
        return out
    }

    // Stage 2: Filter even numbers
    filterEven := func(in <-chan int) <-chan int {
        out := make(chan int)
        go func() {
            defer close(out)
            for n := range in {
                if n%2 == 0 {
                    select {
                    case out <- n:
                    case <-ctx.Done():
                        return
                    }
                }
            }
        }()
        return out
    }

    return filterEven(square(input))
}

References