为什么我在生产者消费者问题中会遇到“go routines are asleep”错误?

huangapple go评论91阅读模式
英文:

Why do I get - go routines are asleep error for producer consumer issue

问题

这是代码 - 一个生产者在go协程中,多个消费者。
生产者正在向通道中传递信息,多个消费者(每个通过一个go协程)应该并行读取它。

func main() {
	alphabetArray := []string{"A", "B", "C"}

	alphabetChannel := make(chan string, 3)
	// 生产者
	go func() {
		for _, alphabet := range alphabetArray {
			alphabetChannel <- alphabet
		}
	}()

	var wg sync.WaitGroup
	// 生成10个消费者,每个消费者都表示为一个go协程。
	for idx := 0; idx < 10; idx++ {
		wg.Add(1)
		go func() {
			for alphabet := range alphabetChannel {
				fmt.Println(alphabet)
			}
		}()
	}
	wg.Wait()
}

这是go playground的链接 - https://go.dev/play/p/yNdATAEexPB

我得到的错误是:

A
B
C
fatal error: all goroutines are asleep - deadlock!

英文:

Here is the code - a producer in go routine and multiple consumers.
The producer is pumping a channel with information and multiple consumers ( each via a go-routine ) should be reading it in parallel.

func main() {
	alphabetArray := []string{&quot;A&quot;, &quot;B&quot;, &quot;C&quot;}

	alphabetChannel := make(chan string, 3)
	// producer.
	go func() {
		for _, alphabet := range alphabetArray {
			alphabetChannel &lt;- alphabet
		}
	}()

	var wg sync.WaitGroup
	// spawn 10 consumers, consumers represented as a go-routine.
	for idx := 0; idx &lt; 10; idx++ {
		wg.Add(1)
		go func() {
			for alphabet := range alphabetChannel {
				fmt.Println(alphabet)
			}
		}()
	}
	wg.Wait()
}

Here is the link to go playground - https://go.dev/play/p/yNdATAEexPB

The error I am getting is this -

A
B
C
fatal error: all goroutines are asleep - deadlock!

答案1

得分: 3

在生产者完成后关闭通道,这样消费者就会知道何时停止:

go func() {
	defer close(alphabetChannel)
	for _, alphabet := range alphabetArray {
		alphabetChannel <- alphabet
	}
}()

让等待组知道消费者何时完成:

go func() {
	defer wg.Done()
	for alphabet := range alphabetChannel {
		fmt.Println(alphabet)
	}
}()
英文:

Close the channel after producer is done, so the consumer would know when to stop:

go func() {
		defer close(alphabetChannel)
		for _, alphabet := range alphabetArray {
			alphabetChannel &lt;- alphabet
		}
	}()

Let the waitgroup know when consumers are done:

go func() {
			defer wg.Done()
			for alphabet := range alphabetChannel {
				fmt.Println(alphabet)
			}
		}()

huangapple
  • 本文由 发表于 2022年12月21日 10:50:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/74870867.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定