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

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

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

问题

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

  1. func main() {
  2. alphabetArray := []string{"A", "B", "C"}
  3. alphabetChannel := make(chan string, 3)
  4. // 生产者
  5. go func() {
  6. for _, alphabet := range alphabetArray {
  7. alphabetChannel <- alphabet
  8. }
  9. }()
  10. var wg sync.WaitGroup
  11. // 生成10个消费者,每个消费者都表示为一个go协程。
  12. for idx := 0; idx < 10; idx++ {
  13. wg.Add(1)
  14. go func() {
  15. for alphabet := range alphabetChannel {
  16. fmt.Println(alphabet)
  17. }
  18. }()
  19. }
  20. wg.Wait()
  21. }

这是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.

  1. func main() {
  2. alphabetArray := []string{&quot;A&quot;, &quot;B&quot;, &quot;C&quot;}
  3. alphabetChannel := make(chan string, 3)
  4. // producer.
  5. go func() {
  6. for _, alphabet := range alphabetArray {
  7. alphabetChannel &lt;- alphabet
  8. }
  9. }()
  10. var wg sync.WaitGroup
  11. // spawn 10 consumers, consumers represented as a go-routine.
  12. for idx := 0; idx &lt; 10; idx++ {
  13. wg.Add(1)
  14. go func() {
  15. for alphabet := range alphabetChannel {
  16. fmt.Println(alphabet)
  17. }
  18. }()
  19. }
  20. wg.Wait()
  21. }

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

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

  1. go func() {
  2. defer close(alphabetChannel)
  3. for _, alphabet := range alphabetArray {
  4. alphabetChannel <- alphabet
  5. }
  6. }()

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

  1. go func() {
  2. defer wg.Done()
  3. for alphabet := range alphabetChannel {
  4. fmt.Println(alphabet)
  5. }
  6. }()
英文:

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

  1. go func() {
  2. defer close(alphabetChannel)
  3. for _, alphabet := range alphabetArray {
  4. alphabetChannel &lt;- alphabet
  5. }
  6. }()

Let the waitgroup know when consumers are done:

  1. go func() {
  2. defer wg.Done()
  3. for alphabet := range alphabetChannel {
  4. fmt.Println(alphabet)
  5. }
  6. }()

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:

确定