我不理解的 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()
缓冲通道可能会导致各种可能的值,您不应该依赖它来保证算法的正确性。
我最近开始学习 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()
缓冲通道可能会导致各种可能的值,您不应该依赖它来保证算法的正确性。