2012-11-07 39 views
3

我试图从golang.org执行一个例子:http://tour.golang.org/#63同Golang代码不同的输出,为什么?

  • 我已经改变了代码来测试究竟Gosched做什么*

你可以看到输出有: enter image description here

hello 
hello 
hello 
hello 
hello 

但是,当我的代码复制到我的Mac OS X 10.8(转到版本1.0.3),输出已经改变: enter image description here XXXXXX $旅途版本 去版本go1.0.3 XXXXXX $去运行,goroutine.go 你好 世界 你好 世界 你好 世界 你好 世界 你好 世界

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

请帮助我,非常感谢。

+1

我去了http://tour.golang.org/#63,输出是hello \ nworld \ n,按照预期重复5次。您的本地运行示例用大写字母打印“World”,表示您未复制并粘贴示例代码。我假设你在某个地方有错误。请记住重置幻灯片,以便获得原始示例代码。 –

+0

谢谢@StephenWeinberg,我确定那些代码是相同的(我已经改变了输出文字进行测试,但现在我改变了它们)。 – MrROY

回答

4

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

在本地,每次调用fmt.Println时,您的代码都会生成调度程序。 Println执行一个系统调用的stdout。所有的系统调用都会产生与运行时相同的方式。

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

+0

你的意思是*所有的系统调用产生相同的方式runtime.Gosched做*?你确定吗?如果它是真的,那么我们何时应该使用runtime.Gosched?谢谢:D – MrROY

+1

是的,在当前的实现中,系统调用会产生收益。你永远不需要使用runtime.Gosched在一个真正的程序。这只适用于非常严格的处理循环。非缓冲通道使用,IO或内存分配将导致收益。在真正的节目中,我从未使用Gosched。 –

+1

@MrROY,似乎对系统调用的收益是最近的变化。我当然能够在旧版本的Go编译器上重现类似玩法的行为。这确实使'Gosched'在大多数普通代码中都过时了。 –

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行。

正确的围棋程序通常使用:

0

这是因为你在呼唤它运行在您的编程环境之外的goroutine。从字面上看,两个线程正在同时执行,并且输出将是随机的。

相关问题