【发布时间】:2014-10-22 01:04:59
【问题描述】:
我一直在关注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")
}
我知道 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)
}
为切片的后半部分启动一个 goroutine,然后为切片的第一部分启动另一个 goroutine,但是值 x 和 y 被分配了两个不同的值。在我看来,sum 函数会将其总和发送到通道 c,然后下一个 sum 会将其总和发送到同一通道 c 那么如何为这两个变量分配两个不同的值呢?频道c 不应该只有一个sum 值吗?
我很欣赏这是一个相当长的问题,但我无法找到这些问题的答案。
【问题讨论】:
标签: concurrency go goroutine