16-第16章-并发控制与锁优化
第16章并发控制与锁优化16.1 并发基础16.1.1 Goroutine 管理// 使用 sync.WaitGroup 等待多个 goroutinefuncProcessTasks(tasks[]Task){varwg sync.WaitGroupfor_,task:rangetasks{wg.Add(1)gofunc(t Task){deferwg.Done()t.Execute()}(task)}wg.Wait()}// 使用 context 控制 goroutine 生命周期funcProcessWithTimeout(ctx context.Context,duration time.Duration)error{ctx,cancel:context.WithTimeout(ctx,duration)defercancel()done:make(chanerror,1)gofunc(){donelt;-doWork()}()select{caselt;-ctx.Done():returnctx.Err()caseerr:lt;-done:returnerr}}16.2 锁的使用16.2.1 sync.Mutex// 互斥锁基本使用typeCounterstruct{mu sync.Mutex valueint}func(c*Counter)Inc(){c.mu.Lock()deferc.mu.Unlock()c.value}func(c*Counter)Value()int{c.mu.Lock()deferc.mu.Unlock()returnc.value}16.2.2 sync.RWMutex// 读写锁读多写少场景typeCachestruct{mu sync.RWMutex datamap[string]interface{}}func(c*Cache)Get(keystring)(interface{},bool){c.mu.RLock()deferc.mu.RUnlock()val,ok:c.data[key]returnval,ok}func(c*Cache)Set(keystring,valueinterface{}){c.mu.Lock()deferc.mu.Unlock()c.data[key]value}16.3 原子操作16.3.1 sync/atomic 包importsync/atomictypeAtomicCounterstruct{valueint64}func(c*AtomicCounter)Inc(){atomic.AddInt64(amp;c.value,1)}func(c*AtomicCounter)Value()int64{returnatomic.LoadInt64(amp;c.value)}func(c*AtomicCounter)CompareAndSwap(old,newint64)bool{returnatomic.CompareAndSwapInt64(amp;c.value,old,new)}16.3.2 原子操作 vs 锁特性原子操作互斥锁适用场景简单操作复杂操作性能高较低复杂度低中可组合性差好16.4 无锁数据结构16.4.1 Channel 作为同步机制// 使用 channel 实现工作池typeWorkerPoolstruct{taskschanTask wg sync.WaitGroup}funcNewWorkerPool(workerCountint)*WorkerPool{pool:amp;WorkerPool{tasks:make(chanTask,100),}fori:0;ilt;workerCount;i{pool.wg.Add(1)gopool.worker()}returnpool}func(p*WorkerPool)worker(){deferp.wg.Done()fortask:rangep.tasks{task.Execute()}}func(p*WorkerPool)Submit(task Task){p.taskslt;-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()deferc.mu.Unlock()// 耗时操作在锁内processData(data)c.value}// 好的做法减少锁持有时间func(c*Counter)ProcessAndIncrement(data[]byte){// 耗时操作在锁外processData(data)c.mu.Lock()c.valuec.mu.Unlock()}16.5.2 锁分段// 分段锁减少锁竞争typeShardedMapstruct{shards[]*shard countint}typeshardstruct{mu sync.RWMutex datamap[string]interface{}}funcNewShardedMap(shardCountint)*ShardedMap{shards:make([]*shard,shardCount)fori:rangeshards{shards[i]amp;shard{data:make(map[string]interface{}),}}returnamp;ShardedMap{shards:shards,count:shardCount,}}func(m*ShardedMap)getShard(keystring)*shard{h:fnv.New32a()h.Write([]byte(key))returnm.shards[h.Sum32()%uint32(m.count)]}func(m*ShardedMap)Get(keystring)(interface{},bool){shard:m.getShard(key)shard.mu.RLock()defershard.mu.RUnlock()val,ok:shard.data[key]returnval,ok}func(m*ShardedMap)Set(keystring,valueinterface{}){shard:m.getShard(key)shard.mu.Lock()defershard.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-08sfsEdgeStore- 让边缘数据存储更简单技术栈- Go语言、sfsDb与EdgeX Foundry。纯golang工业物联网边缘计算技术栈项目地址GitHubGitCode 镜像GitCode