首页 > 解决方案 > 为什么这个 go 程序在它应该完成打印后仍然打印?

问题描述

我实现了生产者-消费者模式,但我看到了一个奇怪的行为。
它不会在多次运行中定期发生一次。

package main

import (
    "fmt"
    "sync"
)

func main() {
    works := make(chan string)
    var wg sync.WaitGroup
    wg.Add(2)
    go func() {
        defer wg.Done()
        generators(2, works)
    }()
    go func() {
        defer wg.Done()
        readers(3, works)
    }()
    wg.Wait()
    fmt.Println("Done!")
}

func generators(numberOfProducers int, works chan string) {
    var wg sync.WaitGroup
    for i := 0; i < numberOfProducers; i++ {
        name := fmt.Sprintf("gen#%d", i)
        wg.Add(1)
        go func() {
            defer wg.Done()
            for i := 0; i < 5; i++ {
                works <- fmt.Sprintf("%s-%d", name, i)
            }
        }()
    }
    wg.Wait()
    close(works)
}

func readers(numberOfConsumers int, works chan string) {
    for i := 0; i < numberOfConsumers; i++ {
        name := fmt.Sprintf("reader #%d", i)
        go func() {
            for task := range works {
                fmt.Println(name, " got ", task)
            }
        }()
    }
}

我期待“完成!” 是屏幕上打印的最后一件事,如下所示:

reader #2  got  gen#0-3
reader #0  got  gen#1-3
<removed repetitive output>
reader #1  got  gen#0-2
Done!

但有时在多次运行后我得到这个:

reader #2  got  gen#0-3
reader #0  got  gen#1-3
<removed repetitive output>
reader #1  got  gen#0-2
Done!
reader #2  got  gen#0-4

为什么在“完成!”之后会打印一些内容!? 如您所见,我正在等待阅读器和生成器完成,然后再开始打印“完成!”。

标签: goproducer-consumer

解决方案


推荐阅读