我是golang的新手。我试图了解 channel 的运作方式,但这确实令人困惑。
我评论了我的问题。有人可以向我解释为什么此代码以这种奇怪的方式运行吗?
package main
import "fmt"
func main() {
slice := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}
c := make(chan int)
go pokeVals(slice, c)
fmt.Println(slice)
fmt.Println("start")
<-c // why 2 "poke"s here?
fmt.Println("-")
<-c // why 0 "poke"s?
//<-c // But if uncommented - 2 more "pokes" here
fmt.Println("end")
}
func pokeVals(values []int, c chan int) {
for _, val := range values {
fmt.Println("poke")
c <- val
}
fmt.Println("overpoked")
}
Golang游乐场链接:https://play.golang.org/p/u__cVyUbNJY
最佳答案
Goroutines同时运行。如何安排它们是您无法控制的,因此,唯一的保证就是如果您使用同步,例如 channel , WaitGroup 或其他同步原语。
从main()
中启动一个goroutine,该例程在循环中发送c
上的值。但是在发送每个值之前,它首先打印"poke"
。因此,即使您没有收到"poke"
,您也可能会看到一个c
打印。如果您确实从c
接收到一个值,则此goroutine中的循环可以继续进行下一次迭代,该迭代再次打印"poke"
,并且即使在main()
goroutine可以打印"-"
之前,它也可能立即执行。这就是您的经验。
原始版本中的main()
goroutine(已注释掉第三个<-c
)终止(在打印"end"
之后)。 main()
返回后,您的应用程序结束,它不会等待其他goroutine完成。这就是您的经验。有关详细信息,请参见No output from goroutine。
如果取消注释第三个<-c
,则main()
必须等待另一个在c
上发送的消息,这意味着它肯定必须在此之前等待"poke"
的打印。一旦pokeVals()
的goroutine能够在c
上发送另一个值,它可能会在下一次迭代的循环中再次打印"poke"
(如果安排的时间比从main()
返回的时间更早),这就是您的经验。
是否看到另外2个"poke"
的输出是不确定的,其中1或2个都是有效结果。
关于go - 为什么使用goroutine channel ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60127124/