I've been playing around with the following code from A Tour of Go, but I don't understand what is going on when I apply some minor changes. The original code is this
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
go say("world")
say("hello")
}
and it produces this
world
hello
hello
world
world
hello
hello
world
world
hello
which is OK: five times hello, five times world. I starts to get strange when I call
say("world")
go say("hello")
Now the output is just
world
world
world
world
world
No hello whatsoever. It gets even weirder with two goroutines
go say("world")
go say("hello")
Now there is no output at all. When I change i < 5 to i < 2 and call
go say("world")
say("hello")
I get
world
hello
hello
What am I missing here?
In the case of
say("world")
go say("hello")
The "world" call must complete before the "hello" goroutine is started. The "hello" goroutine does not run or complete because main returns.
For
go say("world")
go say("hello")
the goroutines do not run or complete because main returns.
Use sync.WaitGroup to prevent main from exiting before the goroutines complete:
func say(wg *sync.WaitGroup, s string) {
defer wg.Done()
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
var wg sync.WaitGroup
wg.Add(2)
go say(&wg, "world")
go say(&wg, "hello")
wg.Wait()
}
playground example
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With