Reputation: 26465
This example taken from tour.golang.org/#63
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")
}
hello
world
hello
world
hello
world
hello
world
hello
Why world
is printed only 4
times instead of 5
?
Edit: The answer can be quoted from golang specification:
Program execution begins by initializing the main package and then invoking the function main. When the function main returns, the program exits. It does not wait for other (non-main) goroutines to complete.
Upvotes: 4
Views: 362
Reputation: 54117
Here is how you solve that synchronization problem properly - with sync.WaitGroup
package main
import (
"fmt"
"sync"
"time"
)
func say(s string, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
func main() {
wg := new(sync.WaitGroup)
wg.Add(2)
go say("world", wg)
go say("hello", wg)
wg.Wait()
fmt.Println("All done")
}
Upvotes: 5
Reputation: 531
Because the calling gorouting terminates before the second one you spawned does. This causes the second to shut down. To illustrate, modify your code slightly:
package main
import (
"fmt"
"time"
)
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Print(i)
fmt.Println(":"+s)
}
}
func main() {
go say("world")
say("hello")
}
Try putting in a "wait" or a sleep to the end of the main function.
Upvotes: 2
Reputation: 42478
When your main function ends your program ends, i.e. all goroutines are terminated.
Your main terminates before go say("world")
is done. If you sleep some time at the end of main you should see the last world.
Upvotes: 5