Go高级教程:其他并发工具

大家好,我是极客老墨。 Goroutine 和 Channel 是 Go 并发的基础,但有些场景它们不够用。频繁创建对象导致 GC 压力大?用 sync.Pool。并发读写 map 会 panic?用 sync.Map。简单的计数器用锁太重?用 atomic。 这篇就聊聊 Go 的高级并发工具,看看它们各自适合什么场景。 sync.Pool:对象复用 频繁创建和销毁大对象会给 GC 带来压力,sync.Pool 用于对象复用。 基本用法 1package main 2 3import ( 4 "fmt" 5 "sync" 6) 7 8// 创建对象池 9var bufferPool = sync.Pool{ 10 // New 函数:池为空时创建新对象 11 New: func() interface{} { 12 fmt.Println("Creating new buffer") 13 return make([]byte, 1024) 14 }, 15} 16 17func main() { 18 // 从池中获取对象 19 buf := bufferPool.Get().([]byte) 20 21 // 使用对象 22 copy(buf, []byte("Hello, World!")) 23 fmt.Println(string(buf[:13])) 24 25 // 归还到池中 26 bufferPool.Put(buf) 27 28 // 再次获取(会复用刚才的对象) 29 buf2 := bufferPool.Get().([]byte) 30 fmt.Println(string(buf2[:13])) // 还是 "Hello, World!" 31} 要点: ...

2025-12-20 · 9 min · 1831 words · 老墨

GoLang教程——并发进阶

大家好,我是极客老墨。 并发编程中,Channel 很好用,但不是万能的。有时候需要更精细的控制:等待一组任务完成、保护共享数据、限制并发数量。这时候就需要 sync 包的同步工具了。 这篇就聊聊 Go 的并发进阶工具,看看它们各自适合什么场景。 WaitGroup:等待组 WaitGroup 用于等待一组 Goroutine 完成,是最常用的同步工具。 基本用法 1import ( 2 "fmt" 3 "sync" 4 "time" 5) 6 7func worker(id int, wg *sync.WaitGroup) { 8 defer wg.Done() // 完成时调用 9 10 fmt.Printf("Worker %d starting\n", id) 11 time.Sleep(time.Second) 12 fmt.Printf("Worker %d done\n", id) 13} 14 15func main() { 16 var wg sync.WaitGroup 17 18 for i := 1; i <= 5; i++ { 19 wg.Add(1) // 增加计数 20 go worker(i, &wg) 21 } 22 23 wg.Wait() // 等待所有完成 24 fmt.Println("All workers completed") 25} 要点: Add(n) 增加计数器 Done() 减少计数器(等价于 Add(-1)) Wait() 阻塞直到计数器为 0 必须传递指针 *sync.WaitGroup 常见错误 1// ❌ 错误:在 goroutine 内部 Add 2go func() { 3 wg.Add(1) // 可能在 Wait 之后执行 4 defer wg.Done() 5 // ... 6}() 7 8// ✅ 正确:在启动前 Add 9wg.Add(1) 10go func() { 11 defer wg.Done() 12 // ... 13}() 批量添加 1func main() { 2 var wg sync.WaitGroup 3 4 // 一次性添加多个 5 wg.Add(5) 6 7 for i := 1; i <= 5; i++ { 8 go func(id int) { 9 defer wg.Done() 10 fmt.Printf("Task %d\n", id) 11 }(i) 12 } 13 14 wg.Wait() 15} Mutex:互斥锁 Mutex 用于保护共享数据,确保同一时间只有一个 Goroutine 访问。 ...

2024-12-05 · 9 min · 1714 words · 老墨