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

huangapple go评论92阅读模式
英文:

Same Golang code different output, why?

问题

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

我已经更改了代码以测试Gosched的确切作用。

你可以看到输出结果如下:
相同的Golang代码,为什么输出不同?

hello
hello
hello
hello
hello

但是当我将这些代码复制到我的Mac OS X 10.8(Go版本1.0.3)上时,输出结果发生了变化:
相同的Golang代码,为什么输出不同?
xxxxxx$ go version
go version go1.0.3
xxxxxx$ go run goroutine.go
hello
world
hello
world
hello
world
hello
world
hello
world

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

请帮我解决这个问题,非常感谢。

英文:

I'm trying to execute an example from golang.org : http://tour.golang.org/#63

  • I Have Changed The Code To Test What Exactly Gosched does.*

You could see the output there is:
相同的Golang代码,为什么输出不同?

hello
hello
hello
hello
hello

But when i copy those code to my Mac OS X 10.8(Go version 1.0.3), the output has changed:
相同的Golang代码,为什么输出不同?
xxxxxx$ go version
go version go1.0.3
xxxxxx$ go run goroutine.go
hello
world
hello
world
hello
world
hello
world
hello
world

According to this answer, i should use runtime.GoSched, but in fact i needn't.So i believe something goes wrong.

Please help me with this, many thanks.

答案1

得分: 4

这里的问题是你有两个不同的实现。

在本地,每次调用fmt.Println时,你的代码都会让出给调度程序。Println会向stdout写入数据,这会进行系统调用。所有的系统调用都会以与runtime.Gosched相同的方式让出。

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

英文:

The issue here is you have two different implementations.

Locally, your code yields to the scheduler each time fmt.Println is called. Println does a write to stdout which does a syscall. All syscalls yield the same way runtime.Gosched does.

play.golang.org is a black box. We don't actually know how it works. However, from the example you gave, it appears play does not do a syscall when fmt.Println is called. This makes sense. They probably replaced os.Stdout with a buffer to hold what is printed.

答案2

得分: 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这一行。也许这是有意的,期望用户注意到这一点并调查问题的原因。语言规范中的程序执行部分说明了以下内容:

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

这个说明解释了为什么程序打印的行数少于10行。

正确的Go程序通常使用:

英文:

The Go Tour code is only an introductory example. The code is simplistic and incorrect. GoTour63 gives the following output (line numbers added):

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

The program should print 10 lines. Notice that the line 10 world is missing. Maybe it is intentional and the user is expected to notice this and to investigate the cause of the problem. The section Program execution in the language specification states the following:

> When the function main returns, the program exits. It does not wait for other (non-main) goroutines to complete.

This statement explains why the program is printing less than 10 lines.

Correct Go programs usually use:

答案3

得分: 0

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

英文:

It is because you are calling a goroutine which runs outside your programming environment. Literally, two threads are getting executed concurrently and the output going to be random is obvious.

huangapple
  • 本文由 发表于 2012年11月7日 10:50:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/13262487.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定