相同的Golang代码输出不同,为什么?

时间:2012-11-07 02:50:41

标签: concurrency go

我正在尝试从golang.org执行一个示例:http://tour.golang.org/#63

  • 我已经更改了代码以测试完全有用的内容。*

你可以看到那里的输出: enter image description here

hello
hello
hello
hello
hello

但是当我将这些代码复制到我的Mac OS X 10.8(Go 1.0.3版)时,输出已经改变: enter image description here     xxxxxx $ go版本     去版本go1.0.3     xxxxxx $ go run goroutine.go     你好     世界     你好     世界     你好     世界     你好     世界     你好     世界

根据这个answer,我应该使用runtime.GoSched,但实际上我不需要。所以我相信出了问题。

请帮助我,非常感谢。

3 个答案:

答案 0 :(得分:4)

这里的问题是你有两种不同的实现方式。

在本地,每次调用fmt.Println时,您的代码都会生成调度程序。 Println对stdout进行写操作,它执行系统调用。所有系统调用的生成方式与runtime.Gosched相同。

play.golang.org是一个黑盒子。我们实际上并不知道它是如何工作的。但是,从您给出的示例中,当调用fmt.Println时,看起来play不会执行系统调用。这是有道理的。他们可能用一个缓冲区替换os.Stdout来保存打印的内容。

答案 1 :(得分:2)

Go Tour代码只是一个介绍性的例子。代码简单且不正确。 GoTour63给出以下输出(添加行号):

1 hello
2 world
3 hello
4 world
5 hello
6 world
7 hello
8 world
9 hello

该程序应打印10行。请注意,缺少行10 world。也许这是故意的,用户应该注意到这一点,并调查问题的原因。语言规范中的Program execution部分说明如下:

  

当函数main返回时,程序退出。它不会等待其他(非主要)goroutines完成。

此声明解释了该程序打印少于10行的原因。

正确的Go程序通常使用:

答案 2 :(得分:0)

这是因为你正在调用一个在你的编程环境之外运行的goroutine。从字面上看,两个线程同时执行,输出是随机的。