3

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: enter image description here

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: enter image description here 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.

Community
  • 1
  • 1
WoooHaaaa
  • 19,732
  • 32
  • 90
  • 138
  • 1
    I went to http://tour.golang.org/#63 and the output was hello\nworld\n repeated 5 times as was intended. Your locally running example prints "World" with a capital letter meaning you did not copy and paste the example code. I assume you have an error somewhere. Remember to reset the slide so you have the original example code. – Stephen Weinberg Nov 07 '12 at 02:55
  • Thanks @StephenWeinberg , i'm sure those code is the same (I have changed the output words for testing, but now i changed them back). – WoooHaaaa Nov 07 '12 at 03:07

3 Answers3

4

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.

Stephen Weinberg
  • 51,320
  • 14
  • 134
  • 113
  • You mean *All syscalls yield the same way runtime.Gosched does* ? Are you sure about that? If its true, so when should we use runtime.Gosched ? Thanks :D – WoooHaaaa Nov 07 '12 at 03:34
  • 1
    Yes, with the current implementations, syscalls yield. You should never need to use runtime.Gosched in a real program. It is only for really tight processing loops. Non-buffered channel use, IO, or memory allocation will cause a yield. In real programs, I have never used Gosched. – Stephen Weinberg Nov 07 '12 at 04:01
  • 1
    @MrROY, seems like yield on syscall is recent change. I certainly was able to reproduce play-like behavior on older versions of Go compiler. This indeed makes `Gosched` obsolete in most of normal code. – Vladimir Matveev Nov 07 '12 at 09:27
  • This is not new, syscalls have always yielded, it is part of the mechanism to prevent syscalls from blocking all goroutines from continuing. Gosched has never been needed for most code. – Stephen Weinberg Nov 14 '12 at 06:12
2

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:

0

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.

ganesh kumar
  • 146
  • 2
  • 7