为了账号安全,请及时绑定邮箱和手机立即绑定

goroutine 是如何工作的?

goroutine 是如何工作的?

Go
慕虎7371278 2021-08-10 21:11:45
我一直在关注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 的程序。我认为这并不能保证你会得到helloworld完美的点缀,但我可能是错的。

频道工作的原因是:

  1. Golang 让你像 VonC 提到的那样做多项分配

  2. Channels empty out,即当您分配cx它时会删除传入通道的第一个总和,当它分配cy它时传入第二个值(我再次认为顺序不是保证,因为x可能有前半部分和y后半部分总和或相反亦然。

如果你把通道想象成一种队列,我认为它更有意义。求和 goroutine 将值推送到队列中,然后赋值按顺序弹出值。


查看完整回答
反对 回复 2021-08-10
  • 2 回答
  • 0 关注
  • 198 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信