首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Goroutine示例需要解释

Goroutine示例需要解释
EN

Stack Overflow用户
提问于 2016-03-28 11:35:32
回答 1查看 245关注 0票数 2

我刚刚开始学习Go并遵循一个教程,其中包含了关于goroutines的以下示例:

代码语言:javascript
复制
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执行其他goroutines,并在某个时候返回。“下面的示例给出了以下输出:

代码语言:javascript
复制
hello
world
hello
world
hello
world
hello
world
hello

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

代码语言:javascript
复制
hello
world
world
world
world
world
hello
hello
hello
hello

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

其实我也不明白结果!为什么不只是

代码语言:javascript
复制
hello

?据我所知,Go程序在执行程序的最后一条语句后退出,因此我认为,在say()作为一个goroutine运行并且它的执行被延迟之后,程序将作为一个普通函数执行下一个say(),然后打印"hello“,然后退出。

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

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-28 12:40:57

第一个输出是由单个核心机器产生的输出。第二个可以由多核产生。

say是一个函数,里面有一个for循环,迭代5次。它确实是一个普通的函数,但是其中有一个对Gosched的调用。Gosched所做的就是告诉运行时暂停执行当前的goroutine,然后启动另一个等待的goroutine。这叫做屈服。

解释第一个输出

这是你可以期望在一台单核机器上得到的输出。一步一步,

go say("world")

在这个步骤中,运行库开始对单独的goroutine执行say("world")调用,并继续主goroutine。但这台机器只有一个核心。因此,这两只猩猩都不能平平淡淡地奔跑。新的goroutine (比如gr A)必须等到正在运行的主要goroutine(比如gr B)结束或停顿(Yeilds)。所以它在等待。主goroutine开始执行say("hello")

现在,在浏览say函数时,gr B运行时遇到了runtime.Gosched()

Gosched调用就像暂停一样。它告诉运行时暂停我并释放另一个等待的goroutine。因此,运行时对gr A进行调度。它从等待的地方开始,也就是,

say("world")

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

解释第二个输出

如果您的机器有多个核心,那么goroutines可以并行运行。你的输出是当你得到它的时候。

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

因此,在一台多核机器中,你不能保证单词的打印顺序。如果你多次运行这个程序,我想你也会看到其他订单的。

您可以将GOMAXPROCs设置为1,并查看该程序如何在一台核心计算机上运行。

代码语言:javascript
复制
func main() {
    runtime.GOMAXPROCS(1)

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

然后您将看到第一个输出。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36261502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档