go - sync.WaitGroup - 为什么在 .wait() 之后出现一个 go 例程

标签 go

从下面我得到:
包装收到蛋糕:草莓蛋糕
包装收到蛋糕:草莓蛋糕
包装收到蛋糕:草莓蛋糕
包装收到蛋糕:草莓蛋糕
我们完成了!
包装收到蛋糕:草莓蛋糕

我没想到“我们完成了!”倒数第二?

package main

import (
    "fmt"
    // "strconv"
    // "time"
    "sync"
)

func makeCakeAndSend(cs chan string, wg *sync.WaitGroup) {
    cakeName := "Strawberry Cake "
    cs <- cakeName
    wg.Done()
}

func receiveCakeAndPack(cs chan string) {
    for s := range cs {
        fmt.Println("Packing received cake: ", s)
    }
}

func main() {
    var wg sync.WaitGroup
    cs := make(chan string)

    wg.Add(5)

    for i := 1; i <= 5; i++ {
        go makeCakeAndSend(cs, &wg)
    }

    // go receiveCakeAndPack(cs)

    go func() {
        for s := range cs {
            fmt.Println("Packing received cake: ", s)
        }
        close(cs)
    }()

    wg.Wait()

    fmt.Println("We are done!")

    var input string
    fmt.Scanln(&input)
}

最佳答案

这很正常。 wg.Wait() 确保所有 goroutine 在我们继续之前完成向 channel 发送数据,它不会同步“Packing received cake”的打印。

当每个人都完成了向 channel 发送数据时, channel 中有一项,对吧?但是 Waitgroup 已经完成了。

所以你有一个竞争条件,主 goroutine 继续“我们完成了”,接收 goroutine 接收并打印。这不是同步的,您无法保证哪个会先发生。

关于go - sync.WaitGroup - 为什么在 .wait() 之后出现一个 go 例程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34575778/

相关文章:

go - 如何避免字符串中出现特殊字符

go - 如何在 Go 中使用基类型设置结构字段

windows - 在 Windows 中调试 Go (golang) 代码

go - 如何使用 channel 广播消息

hadoop - Golang 虚拟文件

戈朗/戈尔姆 : api end point returning only last record

go - Go 中使用动态类型(空接口(interface))的 XML Unmarshal

将 C 数组和指针代码转换为 Go

go - 将指向结构的指针添加到 slice

go - 将 go get 命令更新我本地机器上的包