第16章:并发控制与锁优化

16.1 并发基础

16.1.1 Goroutine 管理

// 使用 sync.WaitGroup 等待多个 goroutine
func ProcessTasks(tasks []Task) {
    var wg sync.WaitGroup
    for _, task := range tasks {
        wg.Add(1)
        go func(t Task) {
            defer wg.Done()
            t.Execute()
        }(task)
    }
    wg.Wait()
}

// 使用 context 控制 goroutine 生命周期
func ProcessWithTimeout(ctx context.Context, duration time.Duration) error {
    ctx, cancel := context.WithTimeout(ctx, duration)
    defer cancel()
    
    done := make(chan error, 1)
    go func() {
        done <- doWork()
    }()
    
    select {
    case <-ctx.Done():
        return ctx.Err()
    case err := <-done:
        return err
    }
}

16.2 锁的使用

16.2.1 sync.Mutex

// 互斥锁基本使用
type Counter struct {
    mu    sync.Mutex
    value int
}

func (c *Counter) Inc() {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.value++
}

func (c *Counter) Value() int {
    c.mu.Lock()
    defer c.mu.Unlock()
    return c.value
}

16.2.2 sync.RWMutex

// 读写锁:读多写少场景
type Cache struct {
    mu    sync.RWMutex
    data  map[string]interface{}
}

func (c *Cache) Get(key string) (interface{}, bool) {
    c.mu.RLock()
    defer c.mu.RUnlock()
    val, ok := c.data[key]
    return val, ok
}

func (c *Cache) Set(key string, value interface{}) {
    c.mu.Lock()
    defer c.mu.Unlock()
    c.data[key] = value
}

16.3 原子操作

16.3.1 sync/atomic 包

import "sync/atomic"

type AtomicCounter struct {
    value int64
}

func (c *AtomicCounter) Inc() {
    atomic.AddInt64(&c.value, 1)
}

func (c *AtomicCounter) Value() int64 {
    return atomic.LoadInt64(&c.value)
}

func (c *AtomicCounter) CompareAndSwap(old, new int64) bool {
    return atomic.CompareAndSwapInt64(&c.value, old, new)
}

16.3.2 原子操作 vs 锁

特性原子操作互斥锁
适用场景简单操作复杂操作
性能较低
复杂度
可组合性

16.4 无锁数据结构

16.4.1 Channel 作为同步机制

// 使用 channel 实现工作池
type WorkerPool struct {
    tasks chan Task
    wg    sync.WaitGroup
}

func NewWorkerPool(workerCount int) *WorkerPool {
    pool := &WorkerPool{
        tasks: make(chan Task, 100),
    }
    
    for i := 0; i < workerCount; i++ {
        pool.wg.Add(1)
        go pool.worker()
    }
    
    return pool
}

func (p *WorkerPool) worker() {
    defer p.wg.Done()
    for task := range p.tasks {
        task.Execute()
    }
}

func (p *WorkerPool) Submit(task Task) {
    p.tasks <- task
}

func (p *WorkerPool) Close() {
    close(p.tasks)
    p.wg.Wait()
}

16.5 锁优化技巧

16.5.1 减少锁持有时间

// 不好的做法:锁持有时间长
func (c *Counter) ProcessAndIncrement(data []byte) {
    c.mu.Lock()
    defer c.mu.Unlock()
    
    // 耗时操作在锁内
    processData(data)
    c.value++
}

// 好的做法:减少锁持有时间
func (c *Counter) ProcessAndIncrement(data []byte) {
    // 耗时操作在锁外
    processData(data)
    
    c.mu.Lock()
    c.value++
    c.mu.Unlock()
}

16.5.2 锁分段

// 分段锁:减少锁竞争
type ShardedMap struct {
    shards []*shard
    count  int
}

type shard struct {
    mu   sync.RWMutex
    data map[string]interface{}
}

func NewShardedMap(shardCount int) *ShardedMap {
    shards := make([]*shard, shardCount)
    for i := range shards {
        shards[i] = &shard{
            data: make(map[string]interface{}),
        }
    }
    return &ShardedMap{
        shards: shards,
        count:  shardCount,
    }
}

func (m *ShardedMap) getShard(key string) *shard {
    h := fnv.New32a()
    h.Write([]byte(key))
    return m.shards[h.Sum32()%uint32(m.count)]
}

func (m *ShardedMap) Get(key string) (interface{}, bool) {
    shard := m.getShard(key)
    shard.mu.RLock()
    defer shard.mu.RUnlock()
    val, ok := shard.data[key]
    return val, ok
}

func (m *ShardedMap) Set(key string, value interface{}) {
    shard := m.getShard(key)
    shard.mu.Lock()
    defer shard.mu.Unlock()
    shard.data[key] = value
}

16.6 实战练习

练习 16.1:无锁队列

实现一个无锁的队列数据结构。

练习 16.2:锁竞争分析

使用 go tool trace 分析锁竞争情况。

练习 16.3:性能对比

对比原子操作、互斥锁、读写锁的性能差异。

16.7 本章小结

本章深入讲解了并发控制和锁优化:

  • Goroutine 管理和同步
  • 互斥锁和读写锁的使用
  • 原子操作
  • 无锁数据结构
  • 锁优化技巧

合理的并发控制是高性能系统的关键。


本书版本:1.0.0
最后更新:2026-03-08
sfsEdgeStore - 让边缘数据存储更简单!🚀
技术栈 - Go语言、sfsDb与EdgeX Foundry。纯golang工业物联网边缘计算技术栈
项目地址GitHub
GitCode 镜像GitCode

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐