osx - Different behavior in go1.5beta2 on MacOS and Linux -
the example taken "a tour of go": https://tour.golang.org/concurrency/1
obviously, program output should have 10 rows: 5 "hello" , 5 "world".
but have on:
- linux - 9 rows
- macos - 10 rows
linux output (9 rows):
$ go run 1.go hello world hello world hello world world hello hello
macos x output (10 rows):
$ go run 1.go hello world world hello hello world hello world hello world
can explain - why?
linux uname -a
:
linux desktop 3.16.0-4-amd64 #1 smp debian 3.16.7-ckt11-1 (2015-05-24) x86_64 gnu/linux
macos x uname -a
:
darwin 14.5.0 darwin kernel version 14.5.0: thu jul 9 22:56:16 pdt 2015; root:xnu-2782.40.6~1/release_x86_64 x86_64
source code tour:
package main import ( "fmt" "time" ) func say(s string) { := 0; < 5; i++ { time.sleep(1000 * time.millisecond) fmt.println(s) } } func main() { go say("world") say("hello") }
from the specification:
program execution begins initializing main package , invoking function
main
. when function invocation returns, program exits. not wait other (non-main
) goroutines complete.
so there no guarantee goroutine printing "world"
have time complete before program exits.
i suspect if run program enough times, see both 9-line , 10-line outputs on both platforms. setting gomaxprocs
environment variable 2 might in triggering problem.
you can fix making main goroutine explicitly wait completion of other goroutine. instance, using channel:
func say(s string, done chan<- bool) { := 0; < 5; i++ { time.sleep(1000 * time.millisecond) fmt.println(s) } done <- true } func main() { c := make(chan bool, 2) go say("world", c) say("hello", c) <-c <-c }
i've added buffer channel say
function can send value without blocking (primarily "hello"
invocation returns). wait receive 2 values channel make sure both invocations have completed.
for more complex programs, sync.waitgroup
type can provide more convenient way wait on multiple goroutines.
Comments
Post a Comment