gpt4 book ai didi

需要 Goroutine 示例解释

转载 作者:IT王子 更新时间:2023-10-29 01:39:14 26 4
gpt4 key购买 nike

我刚刚开始学习 Go 并遵循包含以下 goroutines 示例的教程:

package main

import (
"fmt"
"runtime"
)

func say(s string) {
for i := 0; i < 5; i++ {
runtime.Gosched()
fmt.Println(s)
}
}

func main() {
go say("world") // create a new goroutine
say("hello") // current goroutine
}

它声明“runtime.Gosched() 意味着让 CPU 执行其他 goroutine,并在某个时刻返回。”。示例下方给出了以下输出:

hello
world
hello
world
hello
world
hello
world
hello

然而,当我在我的机器上使用 go run 运行这个例子时,我得到了

hello
world
world
world
world
world
hello
hello
hello
hello

我的 Go 版本是 go version go1.6 darwin/amd64

其实这两个结果我都不明白!为什么不只是

hello

?据我了解 Go 程序在程序的最后一条语句执行后退出,所以我认为 say() 作为 goroutine 运行并且其执行被延迟后,程序执行下一个 say() 作为普通函数,打印“hello”然后退出。

那么哪个结果是正确的,为什么?

最佳答案

第一个输出将由单核机器生成。第二个可以由多核生成。

say 是一个内部有 for 循环的函数,迭代 5 次。它确实是一个普通函数,但其​​中调用了 GoschedGosched 所做的是,它告诉运行时暂停执行当前的 goroutine,而是启动另一个等待的 goroutine。这称为屈服

解释第一个输出

这是您可以期望在单核机器上获得的输出。一步一步来,

go say("world")

在这一步,运行时开始在单独的 goroutine 上执行 say("world") 调用并继续主 goroutine。但是机器只有一个核心。所以两个 goroutines 不能并行运行。新的 goroutine(例如 gr A)必须等到正在运行的主 goroutine(例如 gr B)完成或暂停(yields)。所以它等待。主 goroutine 开始执行 say("hello")

现在通过 gr Bsay 函数运行时遇到 runtime.Gosched()

Gosched 调用就像暂停。它告诉运行时暂停我并安排另一个正在等待的 goroutine。所以运行时调度 gr A。它从它等待的地方开始,也就是,

说(“世界”)

现在 gr A 执行直到遇到它自己的 runtime.Gosched()gr A 暂停。 gr B 醒来并从它离开的地方开始奔跑。 runtime.Gosched() 之后的语句是打印“hello”。所以“你好”被打印出来了。 gr B 继续并进入其 for 循环的下一次迭代。遇见 Gosched。暂停。 gr A 重新启动。打印“世界”。我想您可以看到这是如何进行 5 次,直到它打印给定的输出。

解释第二个输出

如果你的机器有多个核心,goroutines 可以并行运行。你的是你得到的输出。

现在当 go say("world") 被调用时 gr A 不必等到 gr B 完成。它可以立即在另一个核心上启动。因此,当 Gosched 被调用时,可能没有等待的 goroutines。如果当前的暂停,它将立即在另一个核心上启动。

所以在多核机器中你不能保证单词的打印顺序。如果您多次运行该程序,我想您也会看到其他命令。

您可以将 GOMAXPROCs 设置为 1 并查看程序在单核机器上的运行情况。

func main() {
runtime.GOMAXPROCS(1)

go say("world") // create a new goroutine
say("hello") // current goroutine
}

然后你会看到第一个输出。

关于需要 Goroutine 示例解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36261502/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com