我一直在关注Go Tour,但在 Goroutines 方面我有点卡住了。我知道它们非常轻量级,每次一个 goroutine 阻塞时,另一个 goroutine 都会启动,但我无法理解这个示例的实际工作原理:
package main
import (
"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”一次。但是我不明白为什么输出是这样的:
hello
world
hello
world
hello
world
hello
world
hello
根据我对其他语言线程的有限理解,输出应该是这样的:
hello
world
world
world
world
world
或者像这样:
world
world
world
hello
world
world
为什么第二行也执行了五次?go语句下面的任何内容是否归类为 go 例程的一部分?
下一张幻灯片还显示了一些我无法再次理解的内容:
package main
import "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值吗?
我很欣赏这是一个很长的问题,但我无法找到这些问题的答案。
慕莱坞森
相关分类