我一直在关注Go Tour,但在 Goroutines 方面我有点卡住了。我知道它们非常轻量级,每次一个 goroutine 阻塞时,另一个 goroutine 都会启动,但我无法理解这个示例的实际工作原理:package mainimport ( "fmt" "time")func say(s string) { for i := 0; i < 5; i++ { time.Sleep(1000 * time.Millisecond) fmt.Println(s) }}func main() { go say("world") say("hello")}Playground我知道 goroutine 是为带有参数“world”的 say 函数启动的,但据我所知,应该打印“world”五次和“hello”一次。但是我不明白为什么输出是这样的:helloworldhelloworldhelloworldhelloworldhello根据我对其他语言线程的有限理解,输出应该是这样的:helloworldworldworldworldworld或者像这样:world worldworldhelloworldworld为什么第二行也执行了五次?go语句下面的任何内容是否归类为 go 例程的一部分?下一张幻灯片还显示了一些我无法再次理解的内容:package mainimport "fmt"func sum(a []int, c chan int) { sum := 0 for _, v := range a { sum += v } c <- sum // send sum to c}func main() { a := []int{7, 2, 8, -9, 4, 0} c := make(chan int) go sum(a[:len(a)/2], c) go sum(a[len(a)/2:], c) x, y := <-c, <-c // receive from c fmt.Println(x, y, x+y)}Playground为切片的后半部分启动一个 goroutine,然后为切片的第一部分启动另一个 goroutine,但是值x和y已经分配了两个不同的值。我看到它的方式sum函数将它的总和发送到通道c,然后下一个sum将它的总和发送到同一个通道,c那么如何为两个变量分配两个不同的值?频道中不应该c只有一个sum值吗?我很欣赏这是一个很长的问题,但我无法找到这些问题的答案。
2 回答
慕莱坞森
TA贡献1810条经验 获得超4个赞
对于第一个函数,您应该看到呈现的 VonC 样式中的值。hello
打印 5 次的原因也是因为该函数say
打印了 5 次。想象一下没有 goroutine 的程序。我认为这并不能保证你会得到hello
和world
完美的点缀,但我可能是错的。
频道工作的原因是:
Golang 让你像 VonC 提到的那样做多项分配
Channels
empty out
,即当您分配c
给x
它时会删除传入通道的第一个总和,当它分配c
给y
它时传入第二个值(我再次认为顺序不是保证,因为x
可能有前半部分和y
后半部分总和或相反亦然。
如果你把通道想象成一种队列,我认为它更有意义。求和 goroutine 将值推送到队列中,然后赋值按顺序弹出值。
- 2 回答
- 0 关注
- 198 浏览
添加回答
举报
0/150
提交
取消