Go并发常见问题包括:1. Goroutine泄漏,应使用context或关闭channel通知退出;2. 数据竞争,需用局部变量、Mutex或channel避免;3. Channel误用导致panic或死锁,应由发送方关闭且合理设缓冲;4. WaitGroup配对错误,需确保Add与Done匹配。

Go语言的并发编程以简洁高效著称,但使用不当也容易引发一些隐蔽且难以排查的问题。以下是开发者在使用Goroutine和Channel时常见的错误及其规避方法。
1. Goroutine泄漏
当启动的Goroutine因逻辑错误无法正常退出时,就会发生泄漏。这些“僵尸”协程会一直占用内存和资源,严重时可能导致程序崩溃。
常见场景:
- 从无缓冲channel接收数据,但无人发送
- select中监听了永远不会就绪的case
- for循环中的Goroutine未设置退出机制
解决建议: 使用context控制生命周期,或通过关闭channel通知协程退出。例如,向一个用于通知的channel发送信号后关闭它,接收方检测到关闭即退出。
立即学习“go语言免费学习笔记(深入)”;
2. 数据竞争(Data Race)
多个Goroutine同时读写同一变量且缺乏同步机制时,会导致数据不一致。
典型例子: for循环中直接将循环变量传入Goroutine,由于变量被所有协程共享,实际读取的值可能不是预期的。
修复方式:
- 在循环内部创建局部变量:i := i
- 使用sync.Mutex保护共享资源
- 改用channel进行通信而非共享内存
可通过-race编译标志开启竞态检测,在测试阶段发现问题。
3. Channel使用不当
Channel是Go并发的核心工具,但误用会带来死锁或panic。
常见问题包括:
- 向已关闭的channel发送数据,引发panic
- 关闭只接收的channel(编译报错)
- 无缓冲channel两端同时阻塞,导致死锁
最佳实践:
- 只由发送方关闭channel
- 使用ok判断是否能从closed channel接收数据
- 合理设置缓冲区大小避免阻塞
4. WaitGroup使用错误
sync.WaitGroup常用于等待一组Goroutine完成,但常见误用有:
- Add负数导致panic
- Done调用次数超过Add值
- Wait在Goroutine外提前返回
正确做法: 在每个Goroutine开始时复制WaitGroup副本,或确保Add与Done配对。可将wg指针传递给协程函数。
基本上就这些。Go的并发模型虽简单,但细节决定成败。养成良好的编码习惯,配合工具检测,才能写出稳定高效的并发程序。











