You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么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()
}

修复要点

  1. 关闭Channel:生产者完成发送后关闭channel,消费者的range循环会在channel关闭且所有元素被接收后自动终止,避免无限阻塞。
  2. 确保WaitGroup计数归零:在每个消费者goroutine内用defer wg.Done(),保证无论goroutine如何退出,都会将WaitGroup的计数减1,让main函数的wg.Wait()能正常结束。

内容的提问来源于stack exchange,提问作者JavaDeveloper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 20:15:29