为什么Go生产者消费者模型会出现goroutine全部休眠的死锁错误?
问题分析与解决
死锁原因
- Channel未关闭:生产者发送完所有数据后没有关闭
alphabetChannel,10个消费者goroutine会一直阻塞在for alphabet := range alphabetChannel循环上,等待新数据输入。 - WaitGroup未正确收尾:每个消费者goroutine启动时调用了
wg.Add(1),但goroutine内部未调用wg.Done(),导致main函数的wg.Wait()永久阻塞,无法结束。
修复后的代码
package main import ( "fmt" "sync" ) func main() { alphabetArray := []string{"A", "B", "C"} alphabetChannel := make(chan string, 3) // 生产者goroutine go func() { for _, alphabet := range alphabetArray { alphabetChannel <- alphabet } close(alphabetChannel) // 发送完成后关闭channel,告知消费者无新数据 }() var wg sync.WaitGroup // 启动10个消费者goroutine for idx := 0; idx < 10; idx++ { wg.Add(1) go func() { defer wg.Done() // 延迟调用Done,确保goroutine退出时通知WaitGroup for alphabet := range alphabetChannel { fmt.Println(alphabet) } }() } wg.Wait() }
修复要点
- 关闭Channel:生产者完成发送后关闭channel,消费者的
range循环会在channel关闭且所有元素被接收后自动终止,避免无限阻塞。 - 确保WaitGroup计数归零:在每个消费者goroutine内用
defer wg.Done(),保证无论goroutine如何退出,都会将WaitGroup的计数减1,让main函数的wg.Wait()能正常结束。
内容的提问来源于stack exchange,提问作者JavaDeveloper
相关产品推荐
相关产品推荐

