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 · 老墨