从通道消耗的多个例程导致数据丢失

zaR*_*Roc 0 go goroutine

我是Go的新手.在下面的示例中,多个go例程正在从无缓冲的通道中消耗.

代码:

var c = make(chan int)

func f() {
    for val := range c {    
        fmt.Printf("routine 1 : %v\n", val)
    }
}   

func g() {
    fmt.Printf("routine 2 : %v\n", <-c)
}

func main() {
    go f()
    go g()
    c <- 0
    c <- 1
    c <- 2
    c <- 3
    c <- 4
    c <- 5
    close(c) 
}
Run Code Online (Sandbox Code Playgroud)

输出是:

routine 1 : 0
routine 1 : 2
routine 2 : 1
routine 1 : 3
routine 1 : 4
Run Code Online (Sandbox Code Playgroud)

此值缺少值5,永远不会打印!为什么会这样?如果我删除了通话 - go g()它完美无缺.

另外,如果我将频道缓冲,请说:

var c = make(chan int, 10)
Run Code Online (Sandbox Code Playgroud)

根本没有输出.据我所知,对于无缓冲通道,发送在接收完成后完成,而不是缓冲的情况.但是,对于缓冲情况,如果channel还没有发送任何int,那么考虑到nil通道,for循环是否会被阻塞?

请帮忙解决我的疑问.欣赏所有输入.

Fli*_*mzy 6

一旦5被消耗,程序退出.它没有时间打印输出.如果你运行程序足够多次,你可能会发现在某些情况下,确实会在输出关闭之前打印它,但它会纯粹是随机的.

在退出程序之前,您需要添加一些机制来等待您的频道完成.