我不理解的 Go Channels 行为

Go Channels behaviour that i do not understand

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

在第一个 运行 我 运行 带有 [第 13 行] 的程序,然后在主例程中当我在 [第 21 行] 打印通道长度时打印 0 和下一行就在它的 print 2 之后(我说的是主例程制作的第一个 print)。

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

在图片中,您可以在控制台中看到两个不同的打印件,我不明白为什么它们不同[只是因为 add/remove 第 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
*/

您看到的行为是由竞争条件引起的。通常,与其他 goroutine 写入通道的时间相比,您无法确定主 goroutine 何时打印通道的长度。

通过添加 print 语句,你会导致额外的 I/O(到 stdout),这反过来通常意味着 goroutines 放弃执行并被重新安排。所以 Print 改变你的 goroutine 写入通道的速度也就不足为奇了。

在设计带有通道的程序时,切记不要太在意通道上发生并发操作的情况。当您从频道中读取时,频道上会出现一、二或零吗?没有办法知道,因为通道是缓冲的,两个 goroutine 很可能 运行 在现代计算机的多核上并发。 len() 缓冲通道可能会导致各种可能的值,您不应该依赖它来保证算法的正确性。