goroutine 是如何工作的?

我一直在关注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值吗?


我很欣赏这是一个很长的问题,但我无法找到这些问题的答案。


慕虎7371278
浏览 199回答 2
2回答

慕莱坞森

对于第一个函数,您应该看到呈现的 VonC 样式中的值。hello打印 5 次的原因也是因为该函数say打印了 5 次。想象一下没有 goroutine 的程序。我认为这并不能保证你会得到hello和world完美的点缀,但我可能是错的。频道工作的原因是:Golang 让你像 VonC 提到的那样做多项分配Channels&nbsp;empty out,即当您分配c给x它时会删除传入通道的第一个总和,当它分配c给y它时传入第二个值(我再次认为顺序不是保证,因为x可能有前半部分和y后半部分总和或相反亦然。如果你把通道想象成一种队列,我认为它更有意义。求和 goroutine 将值推送到队列中,然后赋值按顺序弹出值。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go