猿问

我不理解的 Go Channels 行为

我最近开始学习 Go,我写过一个案例,我无法理解为什么他会根据仅打印 [第 13 行] 的一行中所做的更改获得两种不同的行为,


在第一次运行中,我使用 [第 13 行] 运行程序,然后在主例程中,当我在 [第 21 行] 打印通道长度时打印 0,在下一行打印 2 之后(我'谈论主要程序制作的第一个印刷品)。


在第二次运行中,我删除了 [第 13 行],然后在第一次打印时,通道的长度为 2。


在图片中,您可以在控制台中看到两个不同的打印件,我不明白为什么它们不同 [只是因为添加/删除第 13 行]。


// Go behavior that I do not understand /:

package main


import "fmt"


func main() {


    mychnl := make(chan string, 2)


    go func(input chan string) {

        input <- "Inp1"

        // If we remove this line the length of the chan in the print will be equal in both prints

        fmt.Println("Tell me why D:")

        input <- "Inp2"

        input <- "Inp3"

        input <- "Inp4"

        close(input)

    }(mychnl)


    for res := range mychnl {

        fmt.Printf("Length of the channel is: %v The received value is: %s length need to be == ", len(mychnl), res)

        fmt.Println(len(mychnl))

    }

}


/*

Output ->

Line 13 = fmt.Println("Tell me why D:")


First run with line 13:

Tell me why D:

Length of the channel is: 0 The received value is: Inp1 length need to be == 2

Length of the channel is: 2 The received value is: Inp2 length need to be == 2

Length of the channel is: 1 The received value is: Inp3 length need to be == 1

Length of the channel is: 0 The received value is: Inp4 length need to be == 0


Second run without line 13:

Length of the channel is: 2 The received value is: Inp1 length need to be == 2

Length of the channel is: 2 The received value is: Inp2 length need to be == 2

Length of the channel is: 1 The received value is: Inp3 length need to be == 1

Length of the channel is: 0 The received value is: Inp4 length need to be == 0

*/

弑天下
浏览 75回答 1
1回答

慕容708150

您看到的行为是由于竞争条件造成的。通常,与其他协程写入通道相比,您无法确定主协程何时打印通道长度。通过添加 print 语句,您会导致额外的 I/O(到 stdout),这反过来通常意味着 goroutines 放弃执行并重新安排。Print因此,改变您的 goroutine 写入通道的速度也就不足为奇了。在设计带有通道的程序时,请记住,当通道上发生并发操作时,您一定不要太在意。当您从频道中读取时,频道上会出现一、二或零吗?没有办法知道,因为通道是缓冲的,两个 goroutine 很可能在现代计算机的多核上同时运行。&nbsp;len()缓冲通道可能会导致各种可能的值,您不应该依赖它来保证算法的正确性。
随时随地看视频慕课网APP

相关分类

Go
我要回答